题解: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;
}

浙公网安备 33010602011771号