BZOJ 3207 花神的嘲讽计划Ⅰ

 题意:给定一个序列,每次询问区间 [l,r] 内是否存在一个长度为K的子串.

 由于K是固定的,字符串hash再离散,然后问题转化成了询问区间[l,r]内是否存在一个要求的数.

 可持久化线段树可切,离线乱搞同样支持,可以试下可持久化01Trie.

 

 1 #include<algorithm>
 2 #include<cstdio>
 3 using namespace std;
 4 #define ll long long
 5 #define FILE "dealing"
 6 #define up(i,j,n) for(int i=j;i<=n;i++)
 7 #define db long double 
 8 #define pii pair<int,int>
 9 #define pb push_back
10 #define mem(a,L) memset(a,0,sizeof(int)*(L+1))
11 template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;}
12 template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;}
13 template<class T> inline T squ(T a){return a*a;}
14 const ll maxn=2000100+10,MAXN=200200,inf=1e9+10,limit=1e7,base=23;
15 int read(){
16     int x=0,f=1,ch=getchar();
17     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
18     while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
19     return x*f;
20 }
21 
22 unsigned long long hash[MAXN],k[MAXN];
23 
24 int n,M,K;
25 int a[MAXN],w[MAXN],root[MAXN];
26 struct query{
27     int l,r;
28     unsigned long long v;
29 }q[MAXN];
30 unsigned long long get(int l,int r){
31     return hash[l]-hash[r+1]*k[r-l+1];
32 }
33 pair<unsigned long long,pii > t[MAXN];
34 int val[MAXN],m;
35 int cnt=0;
36 int c[maxn][2],sum[maxn],Cnt=0;
37 void updata(int o){
38     sum[o]=sum[c[o][0]]+sum[c[o][1]];
39 }
40 void insert(int pre,int& o,int l,int r,int key){
41     o=++Cnt;
42     if(l==r){
43         sum[o]=sum[pre]+1;
44         return;
45     }
46     int mid=(l+r)>>1;
47     if(key>mid)c[o][0]=c[pre][0],insert(c[pre][1],c[o][1],mid+1,r,key);
48     else c[o][1]=c[pre][1],insert(c[pre][0],c[o][0],l,mid,key);
49     updata(o);
50 }
51 bool query(int pre,int o,int l,int r,int key){
52     int mid=(l+r)>>1;
53     if(l==r||!(sum[o]-sum[pre]))return sum[o]-sum[pre];
54     if(key>mid)return query(c[pre][1],c[o][1],mid+1,r,key);
55     else return query(c[pre][0],c[o][0],l,mid,key);
56 }
57 int main(){
58     freopen(FILE".in","r",stdin);
59     freopen(FILE".out","w",stdout);
60     n=read(),M=read(),K=read();
61     up(i,1,n)a[i]=read();
62     k[0]=1;up(i,1,n)k[i]=k[i-1]*base;
63     for(int i=n;i>=1;i--)
64         hash[i]=hash[i+1]*base+a[i];
65     for(int i=1;i<=M;i++){
66         q[i].l=read(),q[i].r=read();
67         unsigned long long u=0;
68         for(int j=1;j<=K;j++)w[j]=read();
69         for(int j=K;j>=1;j--)u=u*base+w[j];
70         q[i].v=u;
71     }
72     for(int i=1;i<=n-K+1;i++)
73         t[++cnt]=make_pair(get(i,i+K-1),make_pair(i,1));
74     for(int i=1;i<=M;i++)
75         t[++cnt]=make_pair(q[i].v,make_pair(i,2));
76     sort(t+1,t+cnt+1);
77     for(int i=1;i<=cnt;i++){
78         if(i==1||t[i].first!=t[i-1].first)m++;
79         if(t[i].second.second==1)val[t[i].second.first]=m;
80         else q[t[i].second.first].v=m;
81     }
82     for(int i=1;i<=n-K+1;i++)
83         insert(root[i-1],root[i],1,m,val[i]);
84     for(int i=1;i<=M;i++){
85         if(query(root[q[i].l-1],root[q[i].r-K+1],1,m,q[i].v))printf("No
");
86         else printf("Yes
");
87     }
88     return 0;
89 }
View Code

 

原文地址:https://www.cnblogs.com/chadinblog/p/6809424.html