BZOJ 3207: 花神的嘲讽计划Ⅰ

来源:互联网 发布:大淘营复制软件 编辑:程序博客网 时间:2024/06/05 03:40

刷点水题舒缓心情

一开始没读懂题以为是查询那些数是不是都在那个区间里

于是开始写主席树,写完发现不对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;}


0 0
原创粉丝点击