您的位置:首页 > 其它

3207: 花神的嘲讽计划Ⅰ 主席树+hash

2016-02-27 08:06 253 查看
由于长度一定,我们直接hash一下然后可持久化线段树判一下是否存在就好啦。

unsigned int被卡 unsigned long long过了

#include<iostream>
#include<cstdio>
#include<algorithm>
#define U unsigned int
#define base 233
#define N 500005
using namespace std;
int n,m,k,cnt,size;
U a
,T
,hash
,num
,table
;
int root
;
int ls[N*10],rs[N*10],sum[N*10];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline int find(U x)
{
int l=1,r=cnt;
while (l<=r)
{
int mid=l+r>>1;
if (table[mid]==x) return mid;
else if (table[mid]<x) l=mid+1;
else r=mid-1;
}
return 0;
}
void update(int l,int r,int x,int &y,int val)
{
y=++size;
ls[y]=ls[x]; rs[y]=rs[x]; sum[y]=sum[x]+1;
if (l==r) return;
int mid=l+r>>1;
if (val<=mid) update(l,mid,ls[x],ls[y],val);
else update(mid+1,r,rs[x],rs[y],val);
}
bool query(int l,int r,int x,int y,int val)
{
if (sum[y]-sum[x]==0) return 0;
int mid=l+r>>1;
if (l==r) return 1;
if (val<=mid) return query(l,mid,ls[x],ls[y],val);
else return query(mid+1,r,rs[x],rs[y],val);
}
int main()
{
n=read(); m=read(); k=read(); T[0]=1;
for (int i=1;i<=n;i++) a[i]=a[i-1]*base+read(),T[i]=T[i-1]*base;
n=n-k+1;
for (int i=1;i<=n;i++)
num[i]=hash[i]=a[i+k-1]-a[i-1]*T[k];
sort(num+1,num+n+1);
table[++cnt]=num[1];
for (int i=2;i<=n;i++)
if (num[i]!=num[i-1]) table[++cnt]=num[i];
for (int i=1;i<=n;i++)
update(1,cnt,root[i-1],root[i],find(hash[i]));
for (int i=1;i<=m;i++)
{
int x=read(),y=read()-k+1;
U now=0;
for (int i=1;i<=k;i++)
now=now*base+read();
int pos=find(now);
if (!pos||y<x) puts("Yes");
else puts(query(1,cnt,root[x-1],root[y],pos)?"No":"Yes");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: