这道题是 KMP 来转移子串中的相对排名.
然后查询排名的话需要用到树状数组.
如果跳 fail 指针的话要把没用元素全部删掉.
code:
#include <bits/stdc++.h>
#define N 1005000
#define setI(s) freopen(s".in","r",stdin)
using namespace std;
int n,m,tot,cm;
int ans[N],fail[N],pre[N];
int p[N],h[N],T[N];
namespace BIT
{
int t[N];
int lowbit(int x) { return x&(-x); }
void update(int x,int v)
{
for(int i=x;i<=m;i+=lowbit(i))
t[i]+=v;
}
int query(int x)
{
int ret=0;
for(int i=x;i;i-=lowbit(i))
ret+=t[i];
return ret;
}
void clr() { for(int i=0;i<N;++i) t[i]=0; }
};
void calc()
{
BIT::clr();
for(int i=1;i<=n;++i)
{
pre[i]=BIT::query(p[i]);
BIT::update(p[i],1);
}
pre[n+1]=-1;
BIT::clr();
for(int i=2,j=0;i<=n;++i)
{
while(j&&BIT::query(p[i])!=pre[j+1])
{
for(int k=i-j;k<i-fail[j];++k)
BIT::update(p[k],-1);
j=fail[j];
}
if(BIT::query(p[i])==pre[j+1])
++j,BIT::update(p[i],1);
fail[i]=j;
}
BIT::clr();
for(int i=1,j=0;i<=m;++i)
{
while(j&&BIT::query(h[i])!=pre[j+1])
{
for(int k=i-j;k<i-fail[j];++k)
{
BIT::update(h[k],-1);
}
j=fail[j];
}
if(BIT::query(h[i])==pre[j+1])
{
++j;
BIT::update(h[i],1);
}
if(j==n) ans[++tot]=i-n+1;
}
}
int main()
{
// setI("input");
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
{
int x;
scanf("%d",&x);
p[i]=x;
}
for(int i=1;i<=m;++i) scanf("%d",&T[i]),h[i]=T[i];
sort(T+1,T+1+m);
cm=unique(T+1,T+1+m)-T-1;
for(int i=1;i<=m;++i)
h[i]=lower_bound(T+1,T+1+cm,h[i])-T;
calc();
printf("%d\n",tot);
for(int i=1;i<=tot;++i)
printf("%d ",ans[i]);
printf("\n");
return 0;
}