首页 > 其他分享 >题解:AT_arc183_b [ARC183B] Near Assignment

题解:AT_arc183_b [ARC183B] Near Assignment

时间:2024-08-26 11:08:08浏览次数:8  
标签:ARC183B int 题解 然后 leq Near xy 操作

题意:

给你长度为 \(N\) 的整数序列 \(A,B\) 以及整数 \(K\) 。

你可以执行下列操作零次或多次。

  • 选择整数 \(i\) 和 \(j\) ( \(1 \leq i,j \leq N\) )。这里, \(|i-j| \leq K\) 必须保持不变。然后,将 \(A_{i}\) 的值改为 \(A_{j}\) 。

判断是否有可能使 \(A\) 与 \(B\) 相同。

分析:

做法参考了官方题解。

首先特判 \(A=B\) 的情况。其次如果 \(B\) 中存在了在 \(A\) 中没有出现的数字,直接输出 "No"。

时光倒流,将操作改为选择相同的 \(B_{i},B_{j}(|i-j| \le K)\)。然后把 \(B_{i}\) 变成 \(*\)(\(*\) 代表万能数字)。

如果一次都操作不了,直接输出 "No"。否则任意操作一次,因此接下来默认 \(B\) 中至少存在一个 \(*\)。

可以发现,\(B\) 的两个相邻的位置可以互相交换。原因如下:

  • 当 \(B\) 中存在 \(*x\) 的情况,把 \(*\) 变成 \(x\),然后操作一次变成 \(x*\)。因此 \(*\) 可以任意移动。

  • 当 \(B\) 中存在 \(xy\) 的情况,先调一个 \(*\) 过来,变成 \(*xy\),然后 \(*xy(yxy) \to yx*\)。不过需要满足 \(k \ge 2\),因此最后要特判 \(k=1\) 的情况。

接下来只需要把 \(B\) 中相同的元素放在一堆 \(xxx\),操作成 \(x**\)。然后把 \(B\) 中非 \(*\) 的匹配到 \(A\),剩下的 \(*\) 直接变。所以直接输出 "Yes"。

如果 \(k=1\),分别把 \(A,B\) 相邻的相同的元素合并成一个,操作后称为 \(A{'},B^{'}\)。那么 \(A\) 能操作成 \(B\) 当且仅当 \(B^{'}\) 是 \(A^{'}\) 的子序列。原因是显然的。

时间复杂度 \(O(Tn)\)。

分析:

#include<bits/stdc++.h>
#define int long long
#define N 300005
using namespace std;

int T, n, k;
int a[N], b[N], A[N], B[N];
vector<int>p[N];
bool z[N];
void Sol() {
    cin >> n >> k;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) cin >> b[i];
    bool flag = 1;
    for(int i = 1; i <= n; i++)
        if(a[i] != b[i]) {
            flag = 0;
            break;
        }
    if(flag) {
        cout << "Yes" << endl;
        return;
    }
    if(k == 1) {
        int cnt1 = 0, cnt2 = 0;
        for(int i = 1; i <= n; i++) {
            if(a[i] != a[i - 1]) A[++cnt1] = a[i];
            if(b[i] != b[i - 1]) B[++cnt2] = b[i];
        }
        int now = 0;
        for(int i = 1; i <= cnt1; i++) {
            if(A[i] == B[now + 1]) {
                now++;
                if(now == cnt2) break;
            }
        }
        if(now == cnt2) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    else {
        for(int i = 1; i <= n; i++) p[i].clear(), z[i] = 0;
        for(int i = 1; i <= n; i++) z[a[i]] = 1;
        for(int i = 1; i <= n; i++) {
            if(!z[b[i]]) {
                cout << "No" << endl;
                return;
            }
            p[b[i]].push_back(i);
        }
        for(int i = 1; i <= n; i++) {
            int len = p[i].size();
            for(int j = 0; j < len - 1; j++)
                if(p[i][j + 1] - p[i][j] <= k) {
                    cout << "Yes" << endl;
                    return;
                }
        }
        
        cout << "No" << endl;
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin >> T;
    while(T--) Sol();

    return 0;
}

标签:ARC183B,int,题解,然后,leq,Near,xy,操作
From: https://www.cnblogs.com/xcs123/p/18380594

相关文章

  • 常见问题解决 --- 如何给一个不支持配置代理的程序抓取https流量数据
    比如我有一个C#编写票务系统,它内嵌浏览器功能,我想抓取它的流量,但是这个客户端不支持配置代理设置解决办法:1.安装配置proxifier开启全局代理服务。安装好后网上有激活码激活一下,点击profile-proxyserver,添加一个代理服务器127.0.0.1,端口8080,协议https。点击profile-prox......
  • Java | Leetcode Java题解之第374题猜数字大小
    题目:题解:publicclassSolutionextendsGuessGame{publicintguessNumber(intn){intleft=1,right=n;while(left<right){//循环直至区间左右端点相同intmid=left+(right-left)/2;//防止计算时溢出......
  • Hitachi Vantara Programming Contest 2024(AtCoder Beginner Contest 368)题解A~D
    A-Cut题意:将数组的后k个字符移到前面思路:可以用rotate()函数让数组中的元素滚动旋转rotate(v.begin(),v.begin()+n-k,v.end());直接输出后k个元素,再输出前n-k个元素for(inti=n-k;i<n;i++)write(v[i]);for(inti=0;i<n-k;i++)write(v[i]);B-Decrease2......
  • 题解:AT_joisc2017_f 鉄道旅行 (Railway Trip)
    题意鉄道旅行(RailwayTrip)分析非常神仙的倍增做法。我们设\(l_{i,j}\)表示从\(i\)点出发,停靠\(2^j\)站后能抵达的最左位置。同理设\(r_{i,j}\)表示从\(i\)点出发,停靠\(2^j\)站后能抵达的最右位置。考虑如何更新这两个状态。因为可以走回头路,所以简单的\(l......
  • 题解:SP3109 STRLCP - Longest Common Prefix
    三倍经验:UVA11996JewelMagicP4036[JSOI2008]火星人题意维护一个字符串\(S\),支持以下操作:\(Q\i\j\):输出\(\operatorname{LCP}(S[i\dotsl],S[j\dotsl])\)\(R\i\char\):用\(char\)替换\(S\)的第\(i\)个字符\(I\i\char\):在\(S\)的第\(i\)......
  • 题解:CF590E Birthday
    题目分析题意给定\(n\)个字符串,要求从中选出若干个组成一个集合,且集合中每个字符串都互不包含。求集合最大包含几个字符串。分析本题弱化版:[ABC354G]SelectStrings就是求一个最长反链,并求构造方案。求构造方案还是比较有意思的。建议先做P4298[CTSC2008]祭祀。一......
  • 题解:P5217 贫穷
    题意维护一个字符串,支持以下操作:\(\texttt{Ixc}\),在第\(x\)个字母后面插入一个\(c\)。\(\texttt{Dx}\),删除第\(x\)个字母。\(\texttt{Rxy}\),反转当前文本中的区间\([x,y]\)。\(\texttt{Px}\),输出初始文本中第\(x\)个字母在当前文本中的位置。特别地,若不存在,......
  • 题解:UVA11996 Jewel Magic
    题意给你一个01串,要求完成以下操作:单点插入。单点删除。区间翻转。查询两点开始的LCP。分析先看查询操作,如何得到LCP的长度?我们可以考虑二分长度\(l\),然后用哈希检验区间\([p1,p1+l-1]\)是否等于区间\([p2,p2+l-1]\)。平衡树维护哈希即可。发现......
  • 题解:AT_abc354_g [ABC354G] Select Strings
    题目分析题意给定\(n\)个字符串,要求从中选出若干个组成一个集合,且集合中每个字符串都互不包含。求集合中字符串的权值的和的最大值。分析首先很容易想到用KMP判两个串是否存在包含关系。考虑建图,将不能同时存在于一个集合中的串的节点相连。然后发现只需求出这个图的最......
  • 题解:P7952 [✗✓OI R1] 天动万象
    提供一种和第一篇题解不同的理解思路。题目分析看到操作\(1\):拿dfs序水水就行了。看到操作\(2\):???特殊情况我们考虑一下特殊情况下操作\(2\)怎么处理。假如这棵树是一条链。设从根到叶节点权值如下:(随便赋的)节点编号123456权值123456如果我们......