zoukankan      html  css  js  c++  java
  • 【BZOJ3926】诸神眷顾的幻想乡(后缀自动机)

    题意:给定一棵树,树的每一个结点都有一个[0..c-1]的数字,问本质不同的由任意两点的路径上的数字组成的字符串的个数

    n<=1e5,c<=10

    度为1的结点不超过20个

    思路:ZJOI2015都4年了……时间真快

    考虑任意一个答案串,可以被看成以一个叶子节点为根的Trie树的子串

    又因为叶子结点个数<=20,可以暴力建SAM在上面跑,最后统计方案数

      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  4000010
     12 #define M  210000
     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=998244353,inv2=(MOD+1)/2;
     27       double eps=1e-6;
     28       ll INF=1e18;
     29       ll inf=5e13;
     30       int dx[4]={-1,1,0,0};
     31       int dy[4]={0,0,-1,1};
     32 
     33 int head[M],vet[M],nxt[M],a[M],d[M],tot,n,c;
     34 
     35 int read()
     36 {
     37    int v=0,f=1;
     38    char c=getchar();
     39    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     40    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     41    return v*f;
     42 }
     43 
     44 int add(int a,int b)
     45 {
     46     nxt[++tot]=head[a];
     47     vet[tot]=b;
     48     head[a]=tot;
     49 }
     50 
     51 struct sam
     52 {
     53     int cnt,t[N][10],
     54     st[N],f[N],bl[N],b[N],sz[N];
     55 
     56     sam()
     57     {
     58         cnt=1;
     59     }
     60 
     61     int add(int p,int x)
     62     {
     63         int np,nq,q;
     64         st[np=++cnt]=st[p]+1;
     65         while(!t[p][x])
     66         {
     67             t[p][x]=np;
     68             p=f[p];
     69         }
     70         if(!p) f[np]=1;
     71          else if(st[p]+1==st[q=t[p][x]]) f[np]=q;
     72           else
     73           {
     74               st[nq=++cnt]=st[p]+1;
     75               memcpy(t[nq],t[q],sizeof t[q]);
     76               f[nq]=f[q];
     77               f[q]=f[np]=nq;
     78               while(t[p][x]==q)
     79               {
     80                  t[p][x]=nq;
     81                  p=f[p];
     82               }
     83           }
     84         return np;
     85     }
     86 
     87     void solve()
     88     {
     89         ll ans=0;
     90         rep(i,1,cnt) ans+=st[i]-st[f[i]];
     91         printf("%lld
    ",ans);
     92     }
     93 
     94 }sam;
     95 
     96 void dfs(int u,int fa,int p)
     97 {
     98     int x=sam.add(p,a[u]);
     99     int e=head[u];
    100     while(e)
    101     {
    102         int v=vet[e];
    103         if(v!=fa) dfs(v,u,x);
    104         e=nxt[e];
    105     }
    106 }
    107 
    108 
    109 int main()
    110 {
    111     //freopen("1.in","r",stdin);
    112     //freopen("1.out","w",stdout);
    113     n=read(),c=read();
    114     rep(i,1,n) a[i]=read();
    115     rep(i,1,n) d[i]=0;
    116     rep(i,1,n-1)
    117     {
    118         int x=read(),y=read();
    119         add(x,y);
    120         add(y,x);
    121         d[x]++; d[y]++;
    122     }
    123     rep(i,1,n)
    124      if(d[i]==1) dfs(i,0,1);
    125     sam.solve();
    126     return 0;
    127 }

     建立部分换了个专门给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  4000010
     12 #define M  210000
     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=998244353,inv2=(MOD+1)/2;
     27       double eps=1e-6;
     28       ll INF=1e18;
     29       ll inf=5e13;
     30       int dx[4]={-1,1,0,0};
     31       int dy[4]={0,0,-1,1};
     32 
     33 int head[M],vet[M],nxt[M],a[M],d[M],tot,n,c,q,nq,np;
     34 
     35 int read()
     36 {
     37    int v=0,f=1;
     38    char c=getchar();
     39    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     40    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     41    return v*f;
     42 }
     43 
     44 int add(int a,int b)
     45 {
     46     nxt[++tot]=head[a];
     47     vet[tot]=b;
     48     head[a]=tot;
     49 }
     50 
     51 struct sam
     52 {
     53     int cnt,ch[N][10],
     54     st[N],fa[N],bl[N],b[N],sz[N];
     55 
     56     sam()
     57     {
     58         cnt=1;
     59     }
     60 
     61     int add(int p,int x)
     62     {
     63         if(ch[p][x])
     64         {
     65             q=ch[p][x];
     66             if(st[q]==st[p]+1) return q;
     67              else
     68              {
     69                  st[nq=++cnt]=st[p]+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;
     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         ll ans=0;
    115         rep(i,1,cnt) ans+=st[i]-st[fa[i]];
    116         printf("%lld
    ",ans);
    117     }
    118 
    119 }sam;
    120 
    121 void dfs(int u,int fa,int p)
    122 {
    123     int x=sam.add(p,a[u]);
    124     int e=head[u];
    125     while(e)
    126     {
    127         int v=vet[e];
    128         if(v!=fa) dfs(v,u,x);
    129         e=nxt[e];
    130     }
    131 }
    132 
    133 
    134 int main()
    135 {
    136     n=read(),c=read();
    137     rep(i,1,n) a[i]=read();
    138     rep(i,1,n) d[i]=0;
    139     rep(i,1,n-1)
    140     {
    141         int x=read(),y=read();
    142         add(x,y);
    143         add(y,x);
    144         d[x]++; d[y]++;
    145     }
    146     rep(i,1,n)
    147      if(d[i]==1) dfs(i,0,1);
    148     sam.solve();
    149     return 0;
    150 }
  • 相关阅读:
    Educational Codeforces Round 20 D. Magazine Ad
    Educational Codeforces Round 20 C. Maximal GCD
    紫书第三章训练2 暴力集
    Educational Codeforces Round 20 B. Distances to Zero
    Educational Codeforces Round 20 A. Maximal Binary Matrix
    紫书第三章训练1 D
    紫书第一章训练1 D -Message Decoding
    HAZU校赛 Problem K: Deadline
    Mutual Training for Wannafly Union #8 D
    紫书第三章训练1 E
  • 原文地址:https://www.cnblogs.com/myx12345/p/11477714.html
Copyright © 2011-2022 走看看