题解:AT_arc195_a [ARC195A] Twice Subsequence

比赛的时候人傻了,对着一个莫名其妙的地方看了一个小时。

题意

给定两个序列 \(A,B\),报告 \(A\) 中是否存在有两个不重合的子序列与 \(B\) 完全相同。

做法

我们显然可以直接顺序去匹配,找到第一个解(找不到就直接无解),并且我们知道这个解一定是字典序最小的解,证明显然,若当前匹配到的数不选的话,则字典序一定更大。

然后我们再从后往前扫一遍,得到的一定是最大字典序的解,证明方法和上面相同。

然后若得到的两个解不同的话,则表明你已经构造出了两个解;如果这两个解相同的话,则意味着字典序最大的解和字典序最小的解相同,则一定最多只有一个解。

CODE

赛时码风比较抽象。

#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N=2e5+100;

int n,m;
int a[N],b[N];
bool sg[N];
int idx,minn=N;

signed main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)   cin>>a[i];
    for(int i=1;i<=m;i++)   cin>>b[i];

    for(int i=1,j=1;i<=m;i++)
    {
        while(a[j]!=b[i] && j<=n)
            j++;
        if(j>n) break;
        sg[j]=true,idx++,j++;
    }//找到字典序最小的解


    if(idx<m)   return cout<<"No"<<endl,0;

    idx=0;
    int t=0;
    for(int i=m,j=n;i;i--)
    {
        while(a[j]!=b[i] && j>0)
            j--;
        if(j==0) break;
        if(sg[j]) t++;//判断两个解是否相同
        idx++;
        j--;
    }

    if(idx<m || t==m)   return cout<<"No"<<endl,0;

    cout<<"Yes"<<endl;

    return 0;
}
posted @ 2025-03-26 09:45  袍蚤  阅读(35)  评论(0)    收藏  举报