码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ_3207_花神的嘲讽计划1_(Hash+主席树)

时间:2016-06-20 23:58:34      阅读:538      评论:0      收藏:0      [点我收藏+]

标签:

描述


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

给出一个长度为\(n\)的串,以及\(m\)个长度为\(k\)的串,求每个长度为\(k\)的串在原串\([x,y]\)区间是否出现过.

 

分析


这道题要求对比长度为\(k\)的串,于是我们把这些串的Hash值都算出来,问题就转化成了求\([x,y]\)的区间中是否出现过某Hash值.

求区间中某一个值出现了多少次,可以用主席树.

 

p.s.

1.学习了主席树指针的写法,比数组慢好多啊...看来有必要去学一学平衡树的数组写法...不过好处是不用自己算空间...

2.这道题自己算空间的话会MLE,所以卡着空间限制就好,估计数据比较小,可以过.

 

数组:

 

技术分享
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn=200000+5,X=27;
 5 typedef unsigned long long ull;
 6 const ull INF=~0ull;
 7 int n,m,k,cnt;
 8 int a[maxn],rt[maxn];
 9 ull s[maxn],x=1;
10 struct node{ int l,r,s; }t[maxn*50];
11 inline int read(int &x){ x=0;int k=1;char c;for(c=getchar();c<0||c>9;c=getchar())if(c==-)k=-1;for(;c>=0&&c<=9;c=getchar())x=x*10+c-0;return x*=k; }
12 void update(ull l,ull r,int &pos,ull d){
13     t[++cnt]=t[pos]; pos=cnt; t[pos].s++;
14     if(l==r) return;
15     ull mid=l+(r-l)/2;
16     if(d<=mid) update(l,mid,t[pos].l,d);
17     else update(mid+1,r,t[pos].r,d);
18 }
19 bool query(int x,int y,ull l,ull r,ull d){
20     if(t[y].s-t[x].s==0) return false;
21     if(l==r) return true;
22     ull mid=l+(r-l)/2;
23     if(d<=mid) return query(t[x].l,t[y].l,l,mid,d);
24     else return query(t[x].r,t[y].r,mid+1,r,d);
25 }
26 int main(){
27     read(n); read(m); read(k);
28     for(int i=1;i<=n;i++){
29         read(a[i]);
30         s[i]=s[i-1]*X+(ull)a[i];
31     }
32     for(int i=1;i<=k;i++) x*=X;
33     for(int i=k;i<=n;i++) rt[i]=rt[i-1], update(0ull,INF,rt[i],s[i]-s[i-k]*x);
34     for(int i=1;i<=m;i++){
35         ull hash=0; bool ans;
36         int l,r; read(l); read(r);
37         for(int j=1,t;j<=k;j++)  hash=hash*X+read(t);
38         if(r+1-l<k) ans=false;
39         else ans=query(rt[l+k-2],rt[r],0ull,INF,hash);
40         ans?puts("No"):puts("Yes");
41     }
42     return 0;
43 }
View Code

 

 

指针:

技术分享
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn=200000+5,X=27;
 5 typedef unsigned long long ull;
 6 const ull INF=~0ull;
 7 int n,m,k,cnt;
 8 int a[maxn];
 9 ull s[maxn],x=1;
10 struct node{
11     node* l,* r; int s;
12     node(){}
13     node(node *l,node* r,int s):l(l),r(r),s(s){}
14 }* rt[maxn],* null;
15 inline int read(int &x){ x=0;int k=1;char c;for(c=getchar();c<0||c>9;c=getchar())if(c==-)k=-1;for(;c>=0&&c<=9;c=getchar())x=x*10+c-0;return x*=k; }
16 node* update(node* t,ull l,ull r,ull d){
17     if(l==r) return new node(null,null,t->s+1);
18     ull mid=l+(r-l)/2;
19     if(d<=mid) return new node(update(t->l,l,mid,d),t->r,t->s+1);
20     else return new node(t->l,update(t->r,mid+1,r,d),t->s+1);
21 }
22 bool query(node* x,node* y,ull l,ull r,ull d){
23     if(y->s-x->s==0) return false;
24     if(l==r) return true;
25     ull mid=l+(r-l)/2;
26     if(d<=mid) return query(x->l,y->l,l,mid,d);
27     else return query(x->r,y->r,mid+1,r,d);
28 }
29 int main(){
30     read(n); read(m); read(k);
31     null=new node;
32     null->l=null, null->r=null, null->s=0;
33     for(int i=1;i<=n;i++){
34         read(a[i]);
35         s[i]=s[i-1]*X+(ull)a[i];
36     }
37     for(int i=1;i<=k;i++) x*=X;
38     rt[k-1]=new node(null,null,0);
39     for(int i=k;i<=n;i++) rt[i]=update(rt[i-1],0ull,INF,s[i]-s[i-k]*x);
40     for(int i=1;i<=m;i++){
41         ull hash=0; bool ans;
42         int l,r; read(l); read(r);
43         for(int j=1,t;j<=k;j++)  hash=hash*X+read(t);
44         if(r+1-l<k) ans=false;
45         else ans=query(rt[l+k-2],rt[r],0ull,INF,hash);
46         ans?puts("No"):puts("Yes");
47     }
48     return 0;
49 }
View Code

 

BZOJ_3207_花神的嘲讽计划1_(Hash+主席树)

标签:

原文地址:http://www.cnblogs.com/Sunnie69/p/5602182.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!