zoukankan      html  css  js  c++  java
  • CF213E Two Permutations 线段树维护哈希值

    当初竟然看成子串了$qwq$,不过老师的$ppt$也错了$qwq$


    由于子序列一定是的排列,所以考虑插入$1$到$m$到$n-m+1$到$n$;

    如何判断呢?可以用哈希$qwq$;

    我们用线段树维护哈希值,合并时用就把左子树的哈希值$x[ls]$在$B$进制下左移$sum[rs]$位,即$x[tr]=x[ls]*p[sum[rs]]+x[rs]$;

    此时就可以向上更新哈希值。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #define ull unsigned long long
    #define ll long long
    #define R register int
    #define md ((l+r)>>1)
    #define ls (tr<<1)
    #define rs (tr<<1|1)
    #define pause (for(R i=1;i<=10000000000;++i))
    #define OUT freopen("out.out","w",stdout)
    using namespace std;
    namespace Fread {
        static char B[1<<15],*S=B,*D=B;
        #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
        inline int g() {
            R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
            do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
        } inline bool isempty(const char& ch) {return ch<=36||ch>=127;}
        inline void gs(char* s) {register char ch; while(isempty(ch=getchar())); do *s++=ch; while(!isempty(ch=getchar()));}
    }using Fread::g; using Fread::gs;
    const int B=23,N=200010;
    int n,m,s[N],a[N],pos[N],ans;
    ull x[N<<2],sum[N<<2],p[N],cnt,hsh;
    inline void upd(int tr,int l,int r) {
        sum[tr]=sum[ls]+sum[rs];
        x[tr]=x[ls]*p[sum[rs]]+x[rs];
    }
    inline void change(int tr,int l,int r,int pos,int d) {
        if(l==r) {sum[tr]+=(d?1:-1); x[tr]=d; return ;} 
        if(pos<=md) change(ls,l,md,pos,d);
        else change(rs,md+1,r,pos,d); upd(tr,l,r);
    }
    signed main() {
    #ifdef JACK
        freopen("NOIPAK++.in","r",stdin);
    #endif 
        m=g(),n=g(); p[0]=1; for(R i=1;i<=m;++i) p[i]=p[i-1]*B;
        for(R i=1;i<=m;++i) s[i]=g(),hsh=hsh*B+s[i],cnt+=p[i-1];
        for(R i=1;i<=n;++i) a[i]=g(),pos[a[i]]=i;
        for(R i=1;i<=n;++i) {
            if(i>m) change(1,1,n,pos[i-m],0);
            change(1,1,n,pos[i],i);
            R d=i-m; if(d>=0&&x[1]==d*cnt+hsh) ++ans;
        } printf("%d
    ",ans);
    } 

    2019.06.15

  • 相关阅读:
    将html转换成image图片png格式
    maven 发布打包部署 命令
    javap 指令集
    国内maven仓库地址
    五行大义
    oracle
    【Centos linux系统】命令行(静默)安装oracle 11gR2
    windows安装mysql-5.7压缩版详细教程
    k8s入门系列之扩展组件(一)DNS安装篇
    k8s入门系列之集群安装篇
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11029377.html
Copyright © 2011-2022 走看看