这道题的话,首先是一个小贪心,枚举完在哪个点相遇之后,要得到这个点向左走多远才可以完成左边的序列,向右边走多远才可以完成右边的序列.这两个都取最小,然后再看一下两边之外的地方是不是有相同的元素,这样的话就差不多了.
但是这样的话预处理比较麻烦.
我的话是使用dp,dp[i]定义为现在这个点开始,是到达了需求序列中第i个点的最右边的开始位置.
转移也是很扯淡…
if(pl!=1)dp[pl]=dp[pl-1];
else dp[pl]=i;
就是这样,然后L[i]=dp[na]
,就是这样了,预处理L和R都是这样搞一下就好了.
然后就是最后求答案的部分了.
首先我们注意到最后的答案一定是一段区间里面的等于最后一个值的数的个数.
因为随着点向右移,左边的端点会向右移,右边的端点也向右移,也就是说,L和R都是随着i的递增而递增的.
而随着点向右移,左边能选的区间会变大,右边能选的区间会变小,所以中间一段能够满足左右同时有相同的数.
所以从左边开始找到第一个满足的位置,从右边开始找到第一个满足的位置,求一下包含的区间内的相同的数的个数就好了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 1000005
using namespace std;
void Rd(int &res){
res=0;char p;
while(p=getchar(),p<'0');
do{
res=(res<<1)+(res<<3)+(p^48);
}while(p=getchar(),p>='0');
}
int fi[M],la[M],n,k,col[M],na,nb,a[M],b[M];
int dp[M],L[M],R[M];
int pos[M];
int ans[M],sum[M];
//L[i]为从i出发,到L[i]才能完成a序列,R[i]同理.
int main(){
Rd(n),Rd(k);
for(int i=1;i<=n;i++)
Rd(col[i]);
Rd(na),Rd(nb);
for(int i=1;i<=na;i++)Rd(a[i]);
for(int i=1;i<=nb;i++)Rd(b[i]);
for(int i=1;i<=na;i++)dp[i]=-1;
memset(pos,-1,sizeof(pos));
for(int i=1;i<=na;i++)pos[a[i]]=i;
for(int i=1;i<=n;i++)
if(pos[col[i]]!=-1){
int pl=pos[col[i]];
if(pl!=1)dp[pl]=dp[pl-1];
else dp[pl]=i;
if(pl==na)L[i]=dp[pl];
else L[i]=-1;
}else L[i]=-1;
memset(pos,-1,sizeof(pos));
for(int i=1;i<=nb;i++)dp[i]=-1;
for(int i=1;i<=nb;i++)pos[b[i]]=i;
for(int i=n;i>=1;i--)
if(pos[col[i]]!=-1){
int pl=pos[col[i]];
if(pl!=1)dp[pl]=dp[pl-1];
else dp[pl]=i;
if(pl==nb)R[i]=dp[pl];
else R[i]=-1;
}else R[i]=-1;
for(int i=1;i<=n;i++)
la[col[i]]=i;
for(int i=n;i>=1;i--)
fi[col[i]]=i;
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+(col[i]==a[na]);
int ll=1,rr=n;
for(int Ri=1,res=1;ll<=n;ll++)
if(L[ll]!=-1&&R[ll]!=-1){
for(;res<L[ll];res++)
if(la[col[res]]>Ri)Ri=la[col[res]];
if(Ri>R[ll])break;
}
for(int Le=n,res=n;rr>=1;rr--)
if(R[rr]!=-1&&L[rr]!=-1){
for(;res>R[rr];res--)
if(fi[col[res]]<Le)Le=fi[col[res]];
if(Le<L[rr])break;
}
if(ll>rr){
puts("0");
return 0;
}
// for(int i=1;i<=n;i++)printf("i:%d L:%d R:%d\n",i,L[i],R[i]);
printf("%d\n",sum[rr]-sum[ll-1]);
for(int i=ll;i<=rr;i++)
if(col[i]==a[na])printf("%d ",i);
putchar('\n');
return 0;
}