Codeforces 213E

来源:互联网 发布:天祥网络 编辑:程序博客网 时间:2024/06/06 10:01

给定两个全排列 |A|=n <= |B|=m
问有多少种不同的d使得数组A里面的所有值全部+d之后
是数组B的子序列
然后就是枚举+0,+1,+2,+3…
hash判断一下

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;typedef long long LL;const int maxn=200010;const int B=10007;int N,M,pos[maxn];LL xp[maxn];LL val,sum;struct IntervalTree{    LL hash[maxn<<2];    int cnt[maxn<<2];    void build(int o,int l,int r){        hash[o]=cnt[o]=0;        if(l==r)return ;        int mid=(l+r)>>1;        build(o<<1,l,mid);        build(o<<1|1,mid+1,r);    }    void pushup(int o){        hash[o]=hash[o<<1]*xp[cnt[o<<1|1]]+hash[o<<1|1];        cnt[o]=cnt[o<<1]+cnt[o<<1|1];    }    void update(int o,int l,int r,int pos,int val,int num){        if(l==r){            hash[o]+=num*val;            cnt[o]+=num;            return;        }        int mid=(l+r)>>1;        if(pos<=mid)update(o<<1,l,mid,pos,val,num);        else update(o<<1|1,mid+1,r,pos,val,num);        pushup(o);    }}tree;int main(){    while(scanf("%d%d",&N,&M)!=EOF){        val=sum=0;        xp[0]=1;        for(int i=1;i<=N;i++){xp[i]=xp[i-1]*B;sum+=xp[i-1];}        for(int i=1;i<=N;i++){            int x;            scanf("%d",&x);            val=val*B+x;        }        for(int i=1;i<=M;i++){            int x;            scanf("%d",&x);            pos[x]=i;        }        tree.build(1,1,M);        int ans=0;        for(int i=1;i<=M;i++){//����ֵ1~M��˳������߶�����            tree.update(1,1,M,pos[i],i,1);            if(i>=N)            {                if(tree.hash[1]-(sum*(i-N))==val)                    ans++;                tree.update(1,1,M,pos[i-N+1],i-N+1,-1);            }        }        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击