山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

bzoj 3207 花神的嘲讽计划Ⅰ(哈希法+主席树)

 

【题目链接】

 

    http://www.lydsy.com/JudgeOnline/problem.php?id=3207

 

【题意】

 

    给定一个文本串,多次询问K长的模式串是否在文本[l,r]区间内出现。

 

【思路】

 

    对文本串每K个长度进行一次hash。

    主席树维护val表示一个hash值 的出现次数。查询只需要找到对应的两棵主席树然后计算val的差值即可。

 

【代码】

 

 1 #include<set>
 2 #include<cmath>
 3 #include<queue>
 4 #include<vector>
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
11 using namespace std;
12 
13 typedef unsigned long long ll;
14 const int N = 2e5+10;
15 
16 ll read() {
17     char c=getchar();
18     ll f=1,x=0;
19     while(!isdigit(c)) {
20         if(c=='-') f=-1; c=getchar();
21     }
22     while(isdigit(c))
23         x=x*10+c-'0',c=getchar();
24     return x*f;
25 }
26 
27 struct Tnode {
28     Tnode *ls,*rs;
29     int val;
30 } *T[N],mempool[N*50],*G=mempool;
31 Tnode * Nw (Tnode*l,Tnode*r,int x) {
32     G->ls=l,G->rs=r,G->val=x;
33     return G++;
34 }
35 
36 Tnode* build(Tnode* p,ll l,ll r,ll pos) {
37     if(l==r) return Nw (0x0,0x0,p->val+1);
38     else {
39         ll mid=l+((r-l)>>1);
40         if(pos<=mid) return Nw (build(p->ls,l,mid,pos),p->rs,p->val);
41         else return Nw (p->ls,build(p->rs,mid+1,r,pos),p->val);
42     }
43 }
44 int query(Tnode*x,Tnode*y,ll l,ll r,ll pos) {
45     if(l==r) return y->val - x->val;
46     else {
47         ll mid=l+((r-l)>>1);
48         if(pos<=mid) return query(x->ls,y->ls,l,mid,pos);
49         else return query(x->rs,y->rs,mid+1,r,pos);
50     }
51 }
52 
53 int n,m,K,a;
54 ll H[N],xp=1,X=233;
55 
56 int main()
57 {
58 //    freopen("in.in","r",stdin);
59 //    freopen("out.out","w",stdout);
60     n=read(),m=read(),K=read();
61     FOR(i,1,n) {
62         a=read();
63         H[i]=H[i-1]*X+a;
64     }
65     FOR(i,1,K) xp*=X;
66     int l,r;
67     
68     T[K-1]=Nw (G,G,0);
69     FOR(i,K,n)
70         T[i]=build(T[i-1],0ull,18446744073709551615ull,H[i]-H[i-K]*xp);
71     FOR(i,1,m) {
72         l=read(),r=read();
73         ll H=0;
74         FOR(j,1,K) {
75             a=read();
76             H=H*X+a;
77         }
78         if(r-l+1<K) { puts("Yes"); continue; }
79         if(query(T[l+K-2],T[r],0ull,18446744073709551615ull,H) > 0) puts("No");
80         else puts("Yes");
81     }
82     return 0;
83 }

 

P.S.原来hash函数写的丑也是会WA的 TAT

 

posted on 2016-03-29 08:51  hahalidaxin  阅读(240)  评论(0编辑  收藏  举报