还没改完 被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 //函数名放不下了
嗯嗯 有一说一,头一次用ull自然溢出 还是自己掌握知识点不够的锅
于是也原样骂自己一次【笑】