[BZOJ3207]花神的嘲讽计划
hash+主席树,把hash值挂到主席树上,查询区间是否存在即可。
(我才不会告诉你我的模数被卡了5发)
#include <iostream>
#include <cstdio>
#include <cstring>
typedef unsigned long long ll;
using namespace std;
int n,m,k,rt[200005],ls[100010*90],rs[200005*45],tot,siz[200005*45];long long a[200005];
const ll mod=998244353LL*157+1;
void update(int &k,int pre,ll l,ll r,ll c) {
ls[k=++tot]=ls[pre],rs[k]=rs[pre],siz[k]=siz[pre]+1;
if(l==r)return;
ll mid=l+r>>1;
if(c<=mid) update(ls[k],ls[pre],l,mid,c);
else update(rs[k],rs[pre],mid+1,r,c);
}
int query(int u,int v,ll l,ll r,ll c) {
if(!v) return 0;
if(l==r) {
if(siz[v]-siz[u]>0) return 1;
return 0;
}
ll mid=l+r>>1;
if(mid<c) return query(rs[u],rs[v],mid+1,r,c);
return query(ls[u],ls[v],l,mid,c);
}
int main() {
scanf("%d%d%d",&n,&m,&k);
for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
for(int i=1; i<=n-k+1; i++) {
ll res=0;
for(int j=0; j<k; j++) res=(res*17ll+a[i+j])%(mod);
update(rt[i],rt[i-1],0,mod,res);
}
for(int i=1,x,y; i<=m; i++) {
ll res=0;
scanf("%d%d",&x,&y);
y-=k-1;
for(ll j=1,tp; j<=k; j++) scanf("%lld",&tp),res=(res*17ll+tp)%(mod);
if(x<=y&&query(rt[x-1],rt[y],0,mod,res)) puts("No");
else puts("Yes");
}
}
我是咸鱼。转载博客请征得博主同意Orz