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;
}
posted @ 2018-11-01 15:20  水题收割者  阅读(201)  评论(0编辑  收藏  举报