看到题目就可以想到hash
然后很自然的联想到可持久化权值线段树
WA:base取了偶数
这道题还可以用莫队做,比线段树快一些
可持久化线段树:
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define uint unsigned int 4 #define ull unsigned long long 5 #define inf 4294967295 6 #define N 100005 7 #define M 100005 8 #define base 100003 9 using namespace std; 10 inline int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 int rt[N],n,m,k,tot,ls[M*40],rs[M*40],sz[M*40]; 17 uint hash[N],bas; 18 void add(int pre,int &x,uint l,uint r,uint pos){ 19 x=++tot;ls[x]=ls[pre],rs[x]=rs[pre];sz[x]=sz[pre]+1; 20 if(l==r)return; 21 uint mid=l/2+r/2;if((l&1)&&(r&1))mid++; 22 if(pos<=mid)add(ls[pre],ls[x],l,mid,pos); 23 else add(rs[pre],rs[x],mid+1,r,pos); 24 } 25 int query(int L,int R,uint l,uint r,uint pos){ 26 if(l==r)return sz[R]-sz[L]; 27 uint mid=l/2+r/2;if((l&1)&&(r&1))mid++; 28 if(pos<=mid)query(ls[L],ls[R],l,mid,pos); 29 else query(rs[L],rs[R],mid+1,r,pos); 30 } 31 int main(){ 32 n=read();m=read();k=read(); 33 hash[0]=0; 34 for(int i=1;i<=n;i++)hash[i]=hash[i-1]*base+(uint)read(); 35 bas=1; 36 for(int i=1;i<=k;i++)bas*=base; 37 for(int i=1;i<=n-k+1;i++)add(rt[i-1],rt[i],1,inf,hash[i+k-1]-hash[i-1]*bas); 38 while(m--){ 39 int x=read(),y=read(); 40 uint ha=0; 41 for(int i=1;i<=k;i++)ha=ha*base+(uint)read(); 42 query(rt[x-1],rt[y-k+1],1,inf,ha)?puts("No"):puts("Yes"); 43 } 44 return 0; 45 }