2019.10.22 csp-s模拟测试82 反思总结

还没改完 被T2搞烦 顺手先把博客发了平静一下

呲牙笑.jpg

T2:

//记录一下改题的心路历程 
//我觉着我思路有问题 但我在头铁的路上渐行渐远 
//呲牙笑.jpg 
//光速抄代码
//再写哈希就去投个胎 呲牙笑.jpg 

//看了看这两天的题突然挺生气 我平时真的不怎么骂人的 呲牙笑 
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e5+10,p=1500007,mod=998244353;
int n,len,cnt1=1,cnt2=1,lens;
char s[2*N],c[2*N];
int tree1[2*N][27],tree2[2*N][27];
unsigned long long hash1[2*N],hash2[2*N],ks[2*N];
long long ans; 
struct du{
    int m;
    #define m 1500007
    int head[2][m+10],Next[2][2*N],tot[2];
    long long siz[2][2*N];
    unsigned long long ver[2][2*N];
    void ins(unsigned long long has,int opt,long long sum){
        unsigned long long x=has%m;
        for(int i=head[opt][x];i;i=Next[opt][i]){
            if(has==ver[opt][i]){
                siz[opt][i]+=sum;
                return;
            }
        }
        ver[opt][++tot[opt]]=has,siz[opt][tot[opt]]=sum,Next[opt][tot[opt]]=head[opt][x],head[opt][x]=tot[opt];
        return;
    }
    long long get(unsigned long long has,int opt){
        unsigned long long x=has%m;
        for(int i=head[opt][x];i;i=Next[opt][i]){
            if(has==ver[opt][i]){
                return siz[opt][i];
            }
        }
        return 0;
    }
}h;
void liu(){
    int now=1;
    unsigned long long has=0;
    for(int i=1;i<=len;i++){//前缀 
        has=has*p+c[i];
        if(!tree1[now][c[i]-'a'])tree1[now][c[i]-'a']=++cnt1;
        h.ins(has,0,1);
        now=tree1[now][c[i]-'a'];
    }
    now=1,has=0;
    for(int i=len;i>=1;i--){//后缀 
        has=has*p+c[i];
        if(!tree2[now][c[i]-'a'])tree2[now][c[i]-'a']=++cnt2;
        h.ins(has,1,1);
        now=tree2[now][c[i]-'a'];
    }
}
void chu(int now,unsigned long long has){
    for(int i=0;i<26;i++){
        if(tree1[now][i]){
            long long val=has*p+i+'a';
            long long sum=h.get(has,0);
            h.ins(val,0,sum);
            dfs1(tree1[now][i],val);
        }
    }
}
void ti(int now,unsigned long long has){
    for(int i=0;i<26;i++){
        if(tree2[now][i]){
            long long val=has*p+i+'a';
            long long sum=h.get(has,1);
            h.ins(val,1,sum);
            dfs2(tree2[now][i],val);
        }
    }
}
long long ren(int x){
    int l=1,r=x,ans1=0,ans2=0;
    while(l<=r){//后缀 
        int mid=(l+r)/2;
        unsigned long long val=hash2[mid]-hash2[x+1]*ks[x-mid+1];
        long long sum=h.get(val,1);
        if(sum){
            ans2=sum;
            r=mid-1; 
        }
        else l=mid+1;
    }
    l=x+1,r=lens;
    while(l<=r){//后缀 
        int mid=(l+r)/2;
        unsigned long long val=hash1[mid]-hash1[x]*ks[mid-x];
        long long sum=h.get(val,0);
        if(sum){
            ans1=sum;
            l=mid+1;
        }
        else r=mid-1;
    }
    return 1ll*ans1*ans2;
}
int xian()
{
    scanf("%s",s+1);
    lens=strlen(s+1);
    ks[0]=1;
    for(int i=1;i<=lens;i++){
        hash1[i]=hash1[i-1]*p+s[i];
        ks[i]=ks[i-1]*p;
    }
    for(int i=lens;i>=1;i--){
        hash2[i]=hash2[i+1]*p+s[i];
    }
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",c+1);
        len=strlen(c+1);
        insert();
    }
    dfs1(1,0);
    dfs2(1,0);
    for(int i=1;i<lens;i++){
        ans+=work(i);
    }
    printf("%lld\n",ans);
    return 0;
}
//si ge ma 
//函数名放不下了 
View Code

 嗯嗯 有一说一,头一次用ull自然溢出 还是自己掌握知识点不够的锅

于是也原样骂自己一次【笑】

猜你喜欢

转载自www.cnblogs.com/chloris/p/11719531.html
今日推荐