• 【字符串哈希】【莫队算法】bzoj3207 花神的嘲讽计划Ⅰ


    既然询问的长度是确定的,那么我们可以将所有长度为K的字串弄个哈希值出来,这样字串存在性=>哈希值存在性。

    自然上溢哈希,base=107比较不错。

    序列长度n=>n-K+1

    询问区间[x,y]=>[x,y-K+1]

    注意特判x是否>y-K+1

    然后我们注意到没有修改,于是将哈希值离散化后,莫队大法好。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef unsigned long long ull;
    int f,C;
    inline void R(int &x){
        C=0;f=1;
        for(;C<'0'||C>'9';C=getchar())if(C=='-')f=-1;
        for(x=0;C>='0'&&C<='9';C=getchar())(x*=10)+=(C-'0');
        x*=f;
    }
    #define N 200001
    #define seed 107
    ull seedK=1;
    int n,m,K,a[N<<1],c[N],en,en2,X;
    int num[N],b[N<<1],sum=1;
    bool anss[N];
    struct Point{ull v;int p;}t[N<<1];
    struct Ask{int l,r,x,p;}Q[N];
    bool operator < (const Point &a,const Point &b){return a.v<b.v;}
    bool operator < (const Ask &a,const Ask &b)
    {return num[a.l]!=num[b.l] ? num[a.l]<num[b.l] : a.r<b.r;}
    void Mo_Make_Block()
    {
        int sum=1,sz=sqrt(n); if(!sz) sz=1;
        for(;sum*sz<n;++sum)
          {
            int r=sum*sz;
            for(int i=(sum-1)*sz+1;i<=r;++i) num[i]=sum;
          }
        for(int i=(sum-1)*sz+1;i<=n;++i) num[i]=sum;
    }
    int main()
    {
    	R(n); R(m); R(K);
    	for(int i=1;i<=K;++i)
    	  seedK=seedK*seed;
    	for(int i=1;i<=n;++i) R(c[i]);
    	ull hs=0;
    	for(int i=1;i<=K;++i) hs=hs*seed+(ull)c[i];
    	for(int i=K+1;i<=n;++i)
    	  {
    	  	t[++en].v=hs; t[en].p=en;
    	  	hs=hs*seed+(ull)c[i];
            hs-=c[en]*seedK;
    	  }
    	t[++en].v=hs; t[en].p=en;
    	int Record=en;
    	for(int i=1;i<=m;++i)
    	  {
    	  	R(Q[i].l); R(Q[i].r);
    	  	Q[i].p=i;
    	  	Q[i].r=Q[i].r-K+1;
    	  	hs=0;
    	  	for(int j=1;j<=K;++j)
    	  	  {
    	  	  	R(X);
    	  	  	hs=hs*seed+(ull)X;
    	  	  }
    	  	t[++en].v=hs; t[en].p=en;
    	  }
    	sort(t+1,t+en+1);
    	a[t[1].p]=++en2;
        for(int i=2;i<=en;++i)
          {
            if(t[i].v!=t[i-1].v) ++en2;
            a[t[i].p]=en2;
          }
        en=Record;
        for(int i=1;i<=m;++i) Q[i].x=a[++en];
    	Mo_Make_Block();
    	sort(Q+1,Q+m+1);
        for(int i=Q[1].l;i<=Q[1].r;++i) ++b[a[i]];
        if(Q[1].l<=Q[1].r) anss[Q[1].p]=b[Q[1].x];
        else anss[Q[1].p]=0;
        for(int i=2;i<=m;++i)
          {
            if(Q[i].l<Q[i-1].l) for(int j=Q[i-1].l-1;j>=Q[i].l;--j) ++b[a[j]];
            else for(int j=Q[i-1].l;j<Q[i].l;++j) --b[a[j]];
            if(Q[i].r<Q[i-1].r) for(int j=Q[i-1].r;j>Q[i].r;--j) --b[a[j]];
            else for(int j=Q[i-1].r+1;j<=Q[i].r;++j) ++b[a[j]];
            if(Q[i].l<=Q[i].r) anss[Q[i].p]=b[Q[i].x];
            else anss[Q[i].p]=0;
          }
        for(int i=1;i<=m;++i) puts(anss[i]?"No":"Yes");
    	return 0;
    }
  • 相关阅读:
    tomcat遇到版本问题
    自定义文件上传的按钮的样式css+js
    js控制Bootstrap 模态框(Modal)插件
    jQuery-DataTables相关的网址
    在页面的el表达式是如何判断null的
    hibernate- Hibernate中多对多的annotation的写法(中间表可以有多个字段)
    apache.commons.compress 压缩,解压
    maven项目project facets中是2.3调整为3.0的解决办法
    eclipse中启动调试maven构建的javaweb项目
    [转]事务传播
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4189188.html
Copyright © 2020-2023  润新知