刷點水題舒緩心情
一開始沒讀懂題以爲是查詢那些數是不是都在那個區間裏
於是開始寫主席樹,寫完發現不對QAQ
題目是求那個區間裏是否存在一個字串和給定串相等
由於串長是一定的,每個節點存以該節點爲結尾的長度爲K的字符串的哈希值
然後用主席樹判斷是否存在即可
(讀錯題後一怒之下把主席樹刪了寫了個特技莫隊,跑得還挺快的)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#include<cstdlib>
#include<ctime>
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l) for(int i=r;i>=l;i--)
#define mmt(a,v) memset(a,v,sizeof(a))
#define tra(i,u) for(int i=head[u];i;i=e[i].next)
using namespace std;
typedef unsigned long long ull;
const int N=100000+5;
const int p=107;
int b[N];
struct Node{
int l,r,id;
ull v;
bool operator < (const Node &x)const{
return b[l]==b[x.l]?((r<x.r)^(b[l]&1)):b[l]<b[x.l];
}
}q[N];
int a[N],n,m,k,tot,cnt[N];
ull h[N],s[N];
bool ans[N];
bool find(ull x){
int t=lower_bound(h+k,h+1+n,x)-h;
if(t>n||h[t]!=x)return false;
return cnt[t]?1:0;
}
int main(){
//freopen("a.in","r",stdin);
scanf("%d%d%d",&n,&m,&k);
rep(i,1,n)scanf("%d",&a[i]),s[i]=s[i-1]*p+a[i];
ull t=1;rep(i,1,k)t*=p;
rep(i,k,n)h[i]=s[i]-s[i-k]*t;
sort(h+k,h+n+1);
rep(i,k,n)a[i]=lower_bound(h+k,h+1+n,s[i]-s[i-k]*t)-h;
int S=sqrt(m+0.5);
rep(i,1,n)b[i]=(i-1)/S;
rep(i,1,m){
scanf("%d%d",&q[i].l,&q[i].r);q[i].id=i;
q[i].l+=k-1;
ull ans=0;
int x;
rep(j,1,k){scanf("%d",&x);ans=ans*p+x;}
q[i].v=ans;
}
sort(q+1,q+1+m);
int ql=1,qr=0;
rep(i,1,m){
while(qr<q[i].r)cnt[a[++qr]]++;
while(ql>q[i].l)cnt[a[--ql]]++;
while(qr>q[i].r)cnt[a[qr--]]--;
while(ql<q[i].l)cnt[a[ql++]]--;
ans[q[i].id]=find(q[i].v);
}
rep(i,1,m)puts(ans[i]?"No":"Yes");
return 0;
}