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 }
  • 相关阅读:
    getchar()详解
    ACM错误提示
    关于printf()函数和浮点数
    PCB蚀刻,盐酸不好买,三氯化铁不方便,用这个吧【转】
    wps自动半角符转全角符取消笔记
    万恶的oj笔记之【111028】
    hdu1142 深搜+dp+最短路径。
    pl2303电路图。。
    sencha touch 监控 Carousel 旋转事件
    正则表达式限制文本框输入内容
  • 原文地址:https://www.cnblogs.com/myx12345/p/11477714.html
Copyright © 2011-2022 走看看