码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-10-22 15:19:50      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:class   模拟   sign   node   dfs   main   src   pre   play   

算了 我在干什么orz

T2:

技术图片
#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 node{
    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 insert(){
    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 dfs1(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 dfs2(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 work(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 main()
{
    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;
}
View Code

 

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

标签:class   模拟   sign   node   dfs   main   src   pre   play   

原文地址:https://www.cnblogs.com/chloris/p/11719531.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!