1 条题解

  • 0
    @ 2025-8-24 22:56:41

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar WaterSun
    ʕ̯•͡˔•̯᷅ʔʕ̯•͡˔•̯᷅ʔʕ̯•͡˔•̯᷅ʔ | /cy | 爱你

    搬运于2025-08-24 22:56:41,当前版本为作者最后更新于2025-08-18 16:57:11,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    更好的阅读体验

    以为是拓扑排序之类的东西,结果一看 tag 是构造,已老实。

    思路

    注意到当 bb 有一段连续相同数的时候,对于最后一个经过这一段的操作必须覆盖整个这一段,因此考虑将一段相同的数缩成一个点,记作 c1,,ckc_1,\dots,c_k

    有解的条件为:cc 序列是 aa 序列的一个子序列。这个条件显然是充要的:

    充分性:记 cic_iaa 中对应 aposia_{pos_i},在 bb 中对应 blirib_{l_i \sim r_i}。我们可以通过先顺序将 posipos_i 推到 lil_i,再逆序将 posipos_i 推到 rir_i 的构造方式将 aa 序列变为 bb 序列。因为 posipos_i 是递增的,所以方案肯定能将 aa 变为 bb;同时因为对于一个需要花两步的 cic_i,长度必定 3\geq 3,因此步数 n\leq n。 必要性:反证法。若 i<j,posi>posj\exist i < j,pos_i > pos_j,分讨 li,rj,posi,posjl_i,r_j,pos_i,pos_j 的位置关系,容易发现无论什么情况都不能使将 ci,cjc_i,c_j 同时合法。

    直接按照证明充分性的构造方式输出即可。

    Code

    #include <bits/stdc++.h>
    #define re register
    #define fst first
    #define snd second
    
    using namespace std;
    
    typedef pair<int,int> pii;
    typedef pair<int,pii> pip;
    const int N = 3e5 + 10;
    int n;
    int arr[N],brr[N];
    vector<pii> v;
    vector<int> pos;
    vector<pip> ans;
    
    inline int read(){
        int r = 0,w = 1;
        char c = getchar();
        while (c < '0' || c > '9'){
            if (c == '-') w = -1;
            c = getchar();
        }
        while (c >= '0' && c <= '9'){
            r = (r << 3) + (r << 1) + (c ^ 48);
            c = getchar();
        }
        return r * w;
    }
    
    int main(){
        n = read();
        for (re int i = 1;i <= n;i++) arr[i] = read();
        for (re int i = 1;i <= n;i++) brr[i] = read();
        for (re int i = 1,lst = 1;i <= n + 1;i++){
            if (brr[i] != brr[lst]){ v.push_back({lst,i - 1}); lst = i; }
        }
        for (re int i = 0,j = 1;i < v.size();i++){
            while (j <= n && arr[j] != brr[v[i].fst]) j++;
            if (j == n + 1) return puts("NO"),0;
            pos.push_back(j);
        }
        for (re int i = 0;i < v.size();i++){
            if (pos[i] > v[i].fst) ans.push_back({0,{v[i].fst,pos[i]}});
        }
        for (re int i = v.size() - 1;~i;i--){
            if (pos[i] < v[i].snd) ans.push_back({1,{pos[i],v[i].snd}});
        } printf("YES\n%d\n",ans.size());
        for (pip p:ans) printf("%c %d %d\n",p.fst ? 'R' : 'L',p.snd.fst - 1,p.snd.snd - 1);
        return 0;
    }
    
    • 1

    信息

    ID
    9901
    时间
    1000ms
    内存
    512MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者