zoukankan      html  css  js  c++  java
  • hdu 5343 MZL's Circle Zhou(后缀自动机)

    题目链接:hdu 5343 MZL's Circle Zhou

    题意:

    给你两个串A,B,问从A,B中选子串x,y,问x+y可以组成多少个不同的串,x和y可以为空。

    题解:

    贴一个官方的题解

     1 #include<bits/stdc++.h>
     2 #define mst(a,b) memset(a,b,sizeof(a))
     3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     4 using namespace std;
     5 using ll=unsigned long long;
     6 
     7 const int N=1e5+7,tyn=26,M=N*2;
     8 struct SAM{
     9     int tr[M][tyn],f[M],ml[M],ed,last,p,x,r,q;
    10     int b[M],d[M]; ll cnt[M];
    11     inline int gid(char x){return x-'a';}
    12     inline void nc(int s,int &p){
    13         ml[p=++ed]=s,f[ed]=cnt[ed]=0,mst(tr[ed],0);
    14     }
    15     void clear(){ed=0,nc(0,last);}
    16     void add(int w){
    17         nc(ml[x=last]+1,p),last=p,cnt[p]=1;
    18         while(x&&!tr[x][w])tr[x][w]=p,x=f[x];
    19         if(!x)f[p]=1;
    20         else if(ml[x]+1==ml[q=tr[x][w]])f[p]=q;
    21         else{
    22             nc(ml[x]+1,r),f[r]=f[q],f[p]=f[q]=r;
    23             memcpy(tr[r],tr[q],sizeof(tr[r]));
    24             while(x&&tr[x][w]==q)tr[x][w]=r,x=f[x];
    25         }
    26     }
    27     void upright(int mx=0){
    28         F(i,0,ed)d[i]=0;
    29         F(i,1,ed)d[mx<ml[i]?mx=ml[i]:ml[i]]++;
    30         F(i,1,mx)d[i]+=d[i-1];
    31         F(i,1,ed)b[d[ml[i]]--]=i;
    32     }
    33     void build(char *s){for(int i=1;s[i];i++)add(gid(s[i]));}
    34 }sam[2];
    35 
    36 
    37 char s[N];
    38 int t;
    39 
    40 void work()
    41 {
    42     for(int i=sam[1].ed;i;--i)
    43     {
    44         int x=sam[1].b[i];
    45         sam[1].cnt[x]=1;
    46         F(j,0,25)
    47         {
    48             int v=sam[1].tr[x][j];
    49             if(v)sam[1].cnt[x]+=sam[1].cnt[v];
    50         }
    51     }
    52 }
    53 
    54 void solve()
    55 {
    56     for(int i=sam[0].ed;i;--i)
    57     {
    58         int x=sam[0].b[i];
    59         sam[0].cnt[x]=0;
    60         F(j,0,25)
    61         {
    62             int v=sam[0].tr[x][j];
    63             if(v)sam[0].cnt[x]+=sam[0].cnt[v];
    64             else sam[0].cnt[x]+=sam[1].cnt[sam[1].tr[1][j]];
    65         }
    66     }
    67     ll ans=sam[0].cnt[1];//x为空的时候已经统计过了
    68     F(i,2,sam[0].ed)ans+=sam[0].ml[i]-sam[0].ml[sam[0].f[i]];//y为空的时候
    69     printf("%llu
    ",ans+1);//+1表示x和y都为空的时候
    70 }
    71 
    72 int main(){
    73     scanf("%d",&t);
    74     while(t--)
    75     {
    76         scanf("%s",s+1);
    77         sam[0].clear(),sam[0].build(s),sam[0].upright();
    78         scanf("%s",s+1);
    79         sam[1].clear(),sam[1].build(s),sam[1].upright();
    80         work();solve();
    81     }
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    2017年陕西省网络空间安全技术大赛WP
    XDCTF2014 Writeup
    TensorFlow入门测试程序
    python计算器
    CentOS安装crontab及使用方法
    在Linux 双机下自己手动实现浮动ip技术
    CentOS 7下安装配置FTP
    encodeURI 解码 编码
    jquery 消息提醒插件 toastmessage
    搭通自己的电脑与GitHub的传输通道
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7593701.html
Copyright © 2011-2022 走看看