zoukankan      html  css  js  c++  java
  • bzoj3926: [Zjoi2015]诸神眷顾的幻想乡(广义SAM)

    3926: [Zjoi2015]诸神眷顾的幻想乡

    题目:传送门 

    简要题意:给出一棵树,每个点有编号和权值,问任意两个节点直接的路径上所有权值按顺序连起来形成的数列不同的个数(A到B和B到A是不一样的)


    题解:

       一道广义SAM的入门题目:和之前的生成魔咒差不多,主要在于对SAM的构造。

       一开始想dfs把每条链插入,很显然发现是错的,不知道根而且会漏情况。

       注意到题目的一个提示:叶子节点不超过20个

       那么考虑每次把这些叶子节点当成根,然后建广义SAM,bfs直接搞,每次记得把last重置为root

       然后直接更新ans啊:ans+=ch[i].dep-ch[ch[i].fail].dep(记得long long)

        PS:状态数:20*100000*2

        


    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 typedef long long LL;
     8 struct SAM
     9 {
    10     int son[15],fail,dep;
    11     SAM(){memset(son,0,sizeof(son));fail=dep=0;}
    12 }ch[4100000];int root,cnt,la;
    13 int a[110000],ru[110000],head,tail;
    14 int add(int k)
    15 {
    16     int x=a[k];
    17     int p=la,np=++cnt;ch[np].dep=ch[p].dep+1;
    18     while(p && ch[p].son[x]==0)ch[p].son[x]=np,p=ch[p].fail;
    19     if(p==0)ch[np].fail=root;
    20     else
    21     {
    22         int q=ch[p].son[x];
    23         if(ch[q].dep==ch[p].dep+1)ch[np].fail=q;
    24         else
    25         {
    26             int nq=++cnt;ch[nq]=ch[q];
    27             ch[nq].dep=ch[p].dep+1;
    28             ch[np].fail=ch[q].fail=nq;
    29             while(p && ch[p].son[x]==q)ch[p].son[x]=nq,p=ch[p].fail;
    30         }
    31     }
    32     return np;
    33 }
    34 int n,c;
    35 struct trnode
    36 {
    37     int x,y,next;
    38 }tr[210000];int len,last[110000];
    39 void ins(int x,int y)
    40 {
    41     len++;tr[len].x=x;tr[len].y=y;
    42     tr[len].next=last[x];last[x]=len;
    43 }
    44 struct node
    45 {
    46     int x,w;
    47 }list[210000];bool v[110000];
    48 void bt(int st)
    49 {
    50     la=root;memset(v,false,sizeof(v));v[st]=true;
    51     node s;s.x=st;s.w=add(st);
    52     list[1]=s;head=1;tail=2;
    53     while(head!=tail)
    54     {
    55         s=list[head];int x=s.x;
    56         for(int k=last[x];k;k=tr[k].next)
    57         {
    58             int y=tr[k].y;
    59             if(v[y]==false)
    60             {
    61                 v[y]=true;
    62                 node t;t.x=y;
    63                 la=s.w;t.w=add(y);
    64                 list[tail++]=t;
    65             }
    66         }
    67         head++;//v[x]=false;
    68     }
    69 }
    70 int main()
    71 {
    72     cnt=0;root=la=++cnt;scanf("%d%d",&n,&c);len=0;memset(last,0,sizeof(last));
    73     for(int i=1;i<=n;i++)scanf("%d",&a[i]);memset(ru,0,sizeof(ru));
    74     for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);ins(x,y);ins(y,x);ru[x]++;ru[y]++;}
    75     for(int i=1;i<=n;i++)if(ru[i]==1)bt(i);
    76     LL ans=0;for(int i=1;i<=cnt;i++)ans+=(LL(ch[i].dep-ch[ch[i].fail].dep));
    77     printf("%lld
    ",ans);
    78     return 0;
    79 }
  • 相关阅读:
    2017-5-15 winform项目总结(知识点补充)
    2017-5-7 time控件 三级联动(省,市,区)
    2017-5-4 进程 线程 用户控件
    2017-5-3 打印控件 MDI 窗体容器 Activated事件
    2017-5-2 对话框控件 MessageBox.Show()用法补充 打开新窗体的3中模式
    窗体移动 窗体阴影API
    2017-4-28 ListView控件学习
    【2017-03-28】JS基础、DOM操作
    【2017-03-24】样式表样式
    【2017-03-24】CSS样式表
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8793283.html
Copyright © 2011-2022 走看看