zoukankan      html  css  js  c++  java
  • 【BZOJ3756】Pty的字符串(广义后缀自动机)

    题意:

     思路:论文题

     建立Trie树的后缀自动机需要换这个长的板子

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int uint;
      5 typedef unsigned long long ull;
      6 typedef pair<int,int> PII;
      7 typedef pair<ll,ll> Pll;
      8 typedef vector<int> VI;
      9 typedef vector<PII> VII;
     10 typedef pair<ll,int>P;
     11 #define N  800010
     12 #define M  8100000
     13 #define fi first
     14 #define se second
     15 #define MP make_pair
     16 #define pi acos(-1)
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
     19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
     20 #define lowbit(x) x&(-x)
     21 #define Rand (rand()*(1<<16)+rand())
     22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
     23 #define ls p<<1
     24 #define rs p<<1|1
     25 
     26 const int MOD=1e9+7,inv2=(MOD+1)/2;
     27       double eps=1e-6;
     28       int INF=1e9;
     29       ll inf=5e13;
     30       int dx[4]={-1,1,0,0};
     31       int dy[4]={0,0,-1,1};
     32 
     33 char s[M];
     34 int p,np,q,nq,k,cas,n;
     35 int pos[N];
     36 
     37 int read()
     38 {
     39    int v=0,f=1;
     40    char c=getchar();
     41    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     42    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     43    return v*f;
     44 }
     45 
     46 struct sam
     47 {
     48     int cnt;
     49     int fa[N<<1],ch[N<<1][26];
     50     int st[N<<1],b[N<<1],bl[N<<1],to[N<<1],size[N<<1];
     51     ll f[N<<1];
     52     sam()
     53     {
     54         cnt=1;
     55     }
     56 
     57     int add(int p,int x)
     58     {
     59         if(ch[p][x])
     60         {
     61             q=ch[p][x];
     62             if(st[q]==st[p]+1)
     63             {
     64                 size[q]++;
     65                 return q;
     66             }
     67              else
     68              {
     69                  st[nq=++cnt]=st[p]+1; size[nq]=1;
     70                  memcpy(ch[nq],ch[q],sizeof ch[q]);
     71                 //t[nq]=t[q];
     72                  fa[nq]=fa[q];
     73                  fa[q]=nq;
     74                  while(ch[p][x]==q)
     75                  {
     76                      ch[p][x]=nq;
     77                      p=fa[p];
     78                  }
     79                  return nq;
     80              }
     81         }
     82          else
     83          {
     84                 st[np=++cnt]=st[p]+1; size[np]=1;
     85                 while(p&&!ch[p][x])
     86                 {
     87                     ch[p][x]=np;
     88                     p=fa[p];
     89                 }
     90                 if(!p) fa[np]=1;
     91                  else
     92                  {
     93                         int q=ch[p][x];
     94                         if(st[q]==st[p]+1) fa[np]=q;
     95                          else
     96                          {
     97                                 nq=++cnt; st[nq]=st[p]+1;
     98                                 memcpy(ch[nq],ch[q],sizeof ch[q]);
     99                                 fa[nq]=fa[q];
    100                                 fa[q]=fa[np]=nq;
    101                                 while(ch[p][x]==q)
    102                                 {
    103                                     ch[p][x]=nq;
    104                                     p=fa[p];
    105                                 }
    106                          }
    107                  }
    108            }
    109         return np;
    110     }
    111 
    112     void solve()
    113     {
    114         //printf("cnt=%d
    ",cnt);
    115         rep(i,1,cnt) b[st[i]]++;
    116         rep(i,1,cnt) b[i]+=b[i-1];
    117         rep(i,1,cnt) bl[b[st[i]]--]=i;
    118         scanf("%s",s+1);
    119         int n=strlen(s+1);
    120         per(i,cnt,1) size[fa[bl[i]]]+=size[bl[i]];
    121         //rep(i,1,cnt) printf("%d
    ",size[i]);
    122         size[1]=0;
    123         rep(i,1,cnt)
    124         {
    125             int p=bl[i];
    126             f[p]=f[fa[p]]+1ll*(st[p]-st[fa[p]])*size[p];
    127         }
    128         ll ans=0;
    129         p=1;
    130         int L=0;
    131         rep(i,1,n)
    132         {
    133             int x=s[i]-'a';
    134             if(ch[p][x]) L++,p=ch[p][x];
    135              else
    136              {
    137                  while(p&&!ch[p][x]) p=fa[p];
    138                  if(p) L=st[p]+1,p=ch[p][x];
    139                   else L=0,p=1;
    140              }
    141              if(p!=1) ans+=f[fa[p]]+1ll*(L-st[fa[p]])*size[p];
    142         }
    143         printf("%lld
    ",ans);
    144     }
    145 
    146 }sam;
    147 
    148 int main()
    149 {
    150     freopen("1.in","r",stdin);
    151     freopen("1.out","w",stdout);
    152     n=read();
    153     pos[1]=1;
    154     rep(i,2,n)
    155     {
    156         int x=read();
    157         scanf("%s",s+1);
    158         pos[i]=sam.add(pos[x],s[1]-'a');
    159     }
    160     sam.solve();
    161     return 0;
    162 }
  • 相关阅读:
    ExtJS4 带清除功能的文本框 triggerfield
    ExtJS 4 MVC 创建 Viewport
    Sql Server 查询重复记录
    oracle 备份数据
    sql server 日期模糊查询
    SQL Server 日期转换成字符串
    Kurento应用开发指南(以Kurento 5.0为模板) 之中的一个:简单介绍,安装与卸载
    magento getCarriers 分析
    用两个小样例来解释单例模式中的“双重锁定”
    POJ 3592--Instantaneous Transference【SCC缩点新建图 &amp;&amp; SPFA求最长路 &amp;&amp; 经典】
  • 原文地址:https://www.cnblogs.com/myx12345/p/11512460.html
Copyright © 2011-2022 走看看