[bzoj3207]花神的嘲讽计划Ⅰ[可持久化线段树,hash]
将每k个数字求一个哈希值,存入可持久化线段树,直接查询即可
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cmath> 7 #include <ctime> 8 9 using namespace std; 10 11 #define INF 0xffffffffU 12 13 int n,m,k,tot; 14 unsigned int Sum[110000]={0}; 15 int val[4100000],Left[4100000],Right[4100000],a[110000],root[110000]; 16 17 void Insert(const unsigned int l,const unsigned int r,const int root_l,int & root_r,const unsigned int d) 18 { 19 val[root_r=++tot]=val[root_l]+1; 20 if(l==r)return ; 21 unsigned int mid=l+((r-l)>>1); 22 if(d<=mid) 23 { 24 Right[root_r]=Right[root_l]; 25 Insert(l,mid,Left[root_l],Left[root_r],d); 26 } 27 else 28 { 29 Left[root_r]=Left[root_l]; 30 Insert(mid+1,r,Right[root_l],Right[root_r],d); 31 } 32 return ; 33 } 34 35 int Query(const unsigned int l,const unsigned int r,const int root_l,const int root_r,const unsigned int d) 36 { 37 if(l==r)return val[root_r]-val[root_l]; 38 unsigned int mid=l+((r-l)>>1); 39 if(d<=mid)return Query(l,mid,Left[root_l],Left[root_r],d); 40 return Query(mid+1,r,Right[root_l],Right[root_r],d); 41 } 42 43 int main() 44 { 45 int i,j; 46 unsigned int t=1; 47 48 scanf("%d%d%d",&n,&m,&k); 49 for(i=1;i<=k;++i)t=t*100003; 50 for(i=1;i<=n;++i) 51 { 52 scanf("%d",&a[i]); 53 Sum[i]=Sum[i-1]*100003+a[i]; 54 } 55 56 for(i=k;i<=n;++i) 57 { 58 Insert(1,INF,root[i-1],root[i],Sum[i]-Sum[i-k]*t); 59 } 60 61 for(i=1;i<=m;++i) 62 { 63 int l,r,b; 64 unsigned int temp=0U; 65 scanf("%d%d",&l,&r); 66 for(j=1;j<=k;++j)scanf("%d",&b),temp=temp*100003+b; 67 printf("%s\n",Query(1,INF,root[l+k-2],root[r],temp)?"No":"Yes"); 68 } 69 70 return 0; 71 }