给出一个
n
≤
1
e
5
n\leq1e5
n≤1e5的字符串,并且给出
m
m
m次查询,每次查询询问子串是否在区间
[
l
,
r
]
[l,r]
[l,r]出现。子串的长度是固定的为
k
k
k。
先预处理出原串中所有长度为
k
k
k的字符串哈希值。然后用一个
m
a
p
map
map离散化。对离散化后的每个点开一个记录左端点的
s
e
t
set
set。每次查询找到对应串的那个
s
e
t
set
set,然而二分判断位置。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=1e5+7;
const int b1=131,b2=1331;
int a[N];
ull hs1[N],hs2[N];
ull P1[N],P2[N];
set<int> s[N];
map< pair<ull,ull> ,int > mp;
int main() {
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
hs1[i]=hs1[i-1]*b1+a[i];
hs2[i]=hs2[i-1]*b2+a[i];
}
P1[0]=P2[0]=1;
for(int i=1;i<=n;i++) {
P1[i]=P1[i-1]*b1;
P2[i]=P2[i-1]*b2;
}
int tot=0;
for(int i=1;i+k-1<=n;i++) {
ull x1=hs1[i+k-1]-hs1[i-1]*P1[k];
ull x2=hs2[i+k-1]-hs2[i-1]*P2[k];
if(mp.count(make_pair(x1,x2))==0) {
mp[make_pair(x1,x2)]=++tot;
}
s[mp[make_pair(x1,x2)]].insert(i);
}
while(m--) {
int l,r,x;
ull val1=0,val2=0;
scanf("%d%d",&l,&r);
for(int i=1;i<=k;i++) {
scanf("%d",&x);
val1=val1*b1+x;
val2=val2*b2+x;
}
if(mp.count(make_pair(val1,val2))==0) puts("Yes");
else {
int id=mp[make_pair(val1,val2)];
set<int>::iterator it=s[id].lower_bound(l);
if(it==s[id].end()||(*it)>r-k+1) puts("Yes");
else puts("No");
}
}
return 0;
}