浅谈主席树:https://www.cnblogs.com/AKMer/p/9956734.html
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3207
每\(k\)位\(hash\)一下,然后直接找区间内有没有\(hash\)值。
时间复杂度:\(O(mlogn)\)
空间复杂度:\(O(nlogn)\)
代码如下:
#include <map>
#include <cstdio>
using namespace std;
const int maxn=1e5+5,base=2333;
map<int,int>s;
int n,m,k,bin=1,id;
int rt[maxn],p[maxn],a[maxn];
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct tree_node {
int cnt,ls,rs;
};
struct chairman_tree{
int tot;
tree_node tree[maxn*18];
void ins(int lst,int &now,int l,int r,int pos) {
now=++tot;tree[now]=tree[lst];
tree[now].cnt++;
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid)ins(tree[lst].ls,tree[now].ls,l,mid,pos);
else ins(tree[lst].rs,tree[now].rs,mid+1,r,pos);
}
bool query(int lst,int now,int l,int r,int pos) {
if(l==r)return tree[now].cnt-tree[lst].cnt>0;
int mid=(l+r)>>1;
if(pos<=mid)return query(tree[lst].ls,tree[now].ls,l,mid,pos);
return query(tree[lst].rs,tree[now].rs,mid+1,r,pos);
}
}T;
int main() {
n=read(),m=read(),k=read();
for(int i=1;i<=k;i++)bin*=base;
for(int i=1;i<=n;i++) {
int x=read();
p[i]=p[i-1]*base+x;
}
for(int i=1;i<=n-k+1;i++) {
int tmp=p[i+k-1]-p[i-1]*bin;
if(!s[tmp])s[tmp]=++id;
a[i]=s[tmp];
}
for(int i=1;i<=n;i++)
T.ins(rt[i-1],rt[i],1,id,a[i]);
for(int i=1;i<=m;i++) {
int x=read(),y=read(),tmp=0;
for(int j=1;j<=k;j++) {
int v=read();
tmp=tmp*base+v;
}
if(y-x+1<k||s[tmp]==0)puts("Yes");
else if(T.query(rt[x-1],rt[y-k+1],1,id,s[tmp]))puts("No");
else puts("Yes");
}
return 0;
}