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\n"); 86 else printf("Yes\n"); 87 } 88 return 0; 89 }