[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 }

 

posted @ 2015-12-31 02:14  Gster  阅读(246)  评论(0编辑  收藏  举报