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 }
  • 相关阅读:
    POJ 3660 Cow Contest (floyd求联通关系)
    POJ 3660 Cow Contest (最短路dijkstra)
    POJ 1860 Currency Exchange (bellman-ford判负环)
    POJ 3268 Silver Cow Party (最短路dijkstra)
    POJ 1679 The Unique MST (最小生成树)
    POJ 3026 Borg Maze (最小生成树)
    HDU 4891 The Great Pan (模拟)
    HDU 4950 Monster (水题)
    URAL 2040 Palindromes and Super Abilities 2 (回文自动机)
    URAL 2037 Richness of binary words (回文子串,找规律)
  • 原文地址:https://www.cnblogs.com/myx12345/p/11512460.html
Copyright © 2011-2022 走看看