【bzoj3926】【Zjoi2015】诸神眷顾的幻想乡

  • 题解:

    • 如果某个子串的端点不是叶子,那么一定是另一个串的子串;
    • 这样只对叶子$dfs$把$20*20$个串插入广义$SAM$就是统计本质不同的串的个数的模板了;
    • 我不太会分析广义$SAM$的空间,但是我知道似乎完全图是有$n-1$条欧拉回路的,所以长度不会超过$2n*(20-1)$,需要卡一卡;
    • 可能后面会补广义的坑吧。。。。
    •  1 #include<bits/stdc++.h>
       2 #define rg register
       3 #define il inline 
       4 #define ll long long
       5 using namespace std;
       6 const int N=100010,M=40;
       7 int n,m,sz,mx[N*M],pa[N*M],s[N],len,col[N],ch[N*M][10],d[N],cnt,a[N],w[N],st[N*M],o,hd[N];
       8 ll val[N*M];
       9 struct Edge{int v,nt;}E[N<<1];
      10 il char gc(){
      11     static char*p1,*p2,S[1000000];
      12     if(p1==p2)p2=(p1=S)+fread(S,1,1000000,stdin);
      13     return(p1==p2)?EOF:*p1++;
      14 } 
      15 il int rd(){
      16     int x=0;char c=gc();
      17     while(c<'0'||c>'9')c=gc();
      18     while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
      19     return x;
      20 }
      21 il void adde(int u,int v){
      22     E[o]=(Edge){v,hd[u]};hd[u]=o++;d[u]++;
      23     E[o]=(Edge){u,hd[v]};hd[v]=o++;d[v]++;
      24 }
      25 il void ins(){
      26     /*
      27     for(int i=1;i<=len;i++)printf("%d ",s[i]);
      28     puts(""); 
      29     */
      30     int lst=1,np,nq,p,q,x;
      31     for(rg int i=1;i<=len;i++){
      32         x=s[i];
      33         p=lst; mx[lst=np=++sz]=mx[p]+1;
      34         while(p&&!ch[p][x])ch[p][x]=np,p=pa[p];
      35         if(!p){pa[np]=1;continue;}
      36         q=ch[p][x];
      37         if(mx[q]==mx[p]+1)pa[np]=q;
      38         else {
      39             mx[nq=++sz]=mx[p]+1;
      40             memcpy(ch[nq],ch[q],sizeof(ch[q]));
      41             pa[nq]=pa[q];pa[q]=pa[np]=nq;
      42             while(p&&ch[p][x]==q)ch[p][x]=nq,p=pa[p];
      43         }
      44     }
      45 }
      46 il void dfs(int u,int fa){
      47     for(rg int i=hd[u];i;i=E[i].nt){
      48         int v=E[i].v;
      49         if(v==fa)continue;
      50         s[++len]=col[v];
      51         dfs(v,u);
      52     }
      53     if(d[u]==1&&fa)ins();
      54     len--;
      55 }
      56 int main(){
      57     #ifndef ONLINE_JUDGE 
      58     freopen("bzoj3926.in","r",stdin);
      59     freopen("bzoj3926.out","w",stdout);
      60     #endif 
      61     n=rd();m=rd();
      62     for(rg int i=1;i<=n;i++)col[i]=rd();
      63     for(rg int i=o=1;i<n;i++)adde(rd(),rd());
      64     sz=1;
      65     for(rg int i=1;i<=n;i++)if(d[i]==1)a[++cnt]=i;
      66     for(int i=1;i<=cnt;i++){
      67         s[len=1]=col[a[i]];
      68         dfs(a[i],0);
      69     }
      70     for(rg int i=1;i<=sz;i++)w[mx[i]]++;
      71     for(rg int i=1;i<=n;i++)w[i]+=w[i-1];
      72     for(rg int i=sz;i;i--)st[w[mx[i]]--]=i;
      73     for(rg int i=sz,u;i;i--){
      74         val[u=st[i]]=1;
      75         for(rg int j=0;j<m;j++){
      76             val[u]+=val[ch[u][j]];
      77         }
      78     }
      79     --val[1];
      80     printf("%lld\n",val[1]);
      81     return 0;
      82 }
      bzoj3926

                

猜你喜欢

转载自www.cnblogs.com/Paul-Guderian/p/10230649.html