• ZROI2018普转提day6t3


    传送门

    分析

    居然卡哈希数,万恶的出题人......

    感觉我这个方法似乎比较呆,我的代码成功成为了全网最慢的代码qwq

    应该是可以直接哈希的

    但由于我哈希学的不好又想练练线段树维护哈希,于是就写了个线段树维护了一下哈希值

    详见代码

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<unordered_map>
    using namespace std;
    #define uli unsigned long long
    const long long HASH = 83;
    const long long mod = 2181271;
    long long pw[11000],d[11000];
    long long len[11000],Ans;
    char s[11000],t1[11000],t2[11000];
    int is[mod+10];
    inline void build(long long le,long long ri,long long wh,long long pl,long long k){
        len[wh]=ri-le+1;
        if(le==ri){
          d[wh]=k%mod;
          return;
        }
        long long mid=(le+ri)>>1;
        if(mid>=pl)build(le,mid,wh<<1,pl,k);
          else build(mid+1,ri,wh<<1|1,pl,k);
        d[wh]=(d[wh<<1]+d[wh<<1|1]*pw[len[wh<<1]]%mod)%mod;
        return;
    }
    struct node {
        long long fi,se;
    };
    inline node q(long long le,long long ri,long long wh,long long x,long long y){
        if(le>=x&&ri<=y)return node{d[wh]%mod,ri-le+1};
        node Ans,a,b;
        long long mid=(le+ri)>>1,cnt=0;
        if(mid>=x)cnt+=1,a=q(le,mid,wh<<1,x,y);
        if(mid<y)cnt+=2,b=q(mid+1,ri,wh<<1|1,x,y);
        if(cnt==1)return a;
        if(cnt==2)return b;
        return node{(a.fi+b.fi*pw[a.se]%mod)%mod,a.se+b.se};
    }
    int main(){
        long long n,m1,m2,i,j,k;
        scanf("%s",s);
        n=strlen(s);
        pw[0]=1;
        for(i=1;i<n;i++)pw[i]=pw[i-1]*HASH%mod;
        long long h1=0,h2=0;
        scanf("%s",t1);
        m1=strlen(t1);
        for(i=0;i<m1;i++)
          h1=(h1+(t1[i]-'a')*pw[i]%mod)%mod;
        scanf("%s",t2);
        m2=strlen(t2);
        for(i=0;i<m2;i++)
          h2=(h2+(t2[i]-'a')*pw[i]%mod)%mod;
        for(i=0;i<n;i++)
          build(0,n-1,1,i,s[i]-'a');
        memset(is,-1,sizeof(is)); 
        for(i=max(m1,m2);i<=n;i++)
          for(j=0;j+i-1<n;j++){
              long long hsh=q(0,n-1,1,j,j+i-1).fi;
              if(is[hsh]==i)continue;
              if(q(0,n-1,1,j,j+m1-1).fi==h1&&
                 q(0,n-1,1,j+i-m2,j+i-1).fi==h2)Ans++;
              is[hsh]=i;
          }
        cout<<Ans;
        return 0;
    }
  • 相关阅读:
    Linux
    CUDA开发
    Linux C++
    Python
    C++
    模式识别
    Linux
    算法
    算法
    leetcode 数组,链表,跳表
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9889466.html
Copyright © 2020-2023  润新知