[BZOJ3926]ZJOI2015诸神眷顾的幻想乡|后缀自动机
2015-06-20 22:19
357 查看
注意到非常关键的条件,只与一个空地相邻的空地数量不超过20个,也就是叶子不超过20个,这意味着啥?考虑u到v的路径,一定存在某个叶子,当以这个叶子为根的时候u是v的祖先,也就是说所有的序列都是某个叶子为根的树的一条直链,把一棵树看出一个trie那么我们要做的就是统计这最多20个trie拼成的大trie的不重复子串数量啦!陈老师是厉害呀…
窝只会SAM做法。。按大trie建出SAM,然后可以像3998那样统计。。或者考虑一个子串,它一定是由它的parent对应的串在前面加上一些字符得到,可以加几个呢?那不就是l[i]−l[fa[i]]l[i]-l[fa[i]]嘛。。那么当到fa[i]的子串计算完之后走到i只要加上上面那个东西就好了,所以答案就是∑节点数i=1(l[i]−l[fa[i]])\sum_{i=1}^{节点数}(l[i]-l[fa[i]])。。
窝只会SAM做法。。按大trie建出SAM,然后可以像3998那样统计。。或者考虑一个子串,它一定是由它的parent对应的串在前面加上一些字符得到,可以加几个呢?那不就是l[i]−l[fa[i]]l[i]-l[fa[i]]嘛。。那么当到fa[i]的子串计算完之后走到i只要加上上面那个东西就好了,所以答案就是∑节点数i=1(l[i]−l[fa[i]])\sum_{i=1}^{节点数}(l[i]-l[fa[i]])。。
#include<cstdio> #include<iostream> #include<memory.h> #define N 4000005 using namespace std; struct edge{ int e,next; }ed[200005]; int n,c,s,e,ne=0,nd=1,i,a [10],col[100005],l ,fa ,du[100005],h[100005],u ; long long ans,f ; void add(int s,int e) { ed[++ne].e=e;ed[ne].next=h[s];h[s]=ne; } int extend(int p,int c) { int np=++nd; l[np]=l[p]+1; while (p&&!a[p][c]) a[p][c]=np,p=fa[p]; if (!p) fa[np]=1; else { int q=a[p][c]; if (l[p]+1==l[q]) fa[np]=q; else { int nq=++nd; l[nq]=l[p]+1;fa[nq]=fa[q]; fa[q]=fa[np]=nq; memcpy(a[nq],a[q],sizeof(a[q])); while (a[p][c]==q) a[p][c]=nq,p=fa[p]; } } return np; } void dfs(int x,int fa,int p) { int t=extend(p,col[x]); for (int i=h[x];i;i=ed[i].next) if (ed[i].e!=fa) dfs(ed[i].e,x,t); } void dp(int x) { u[x]=f[x]=1; for (int i=0;i<c;i++) if (a[x][i]) { if (!u[a[x][i]]) dp(a[x][i]); f[x]+=f[a[x][i]]; } } int main() { freopen("3926.in","r",stdin); scanf("%d%d",&n,&c); memset(h,0,sizeof(h));memset(du,0,sizeof(du)); for (i=1;i<=n;i++) scanf("%d",&col[i]); for (i=1;i<n;i++) { scanf("%d%d",&s,&e); add(e,s);add(s,e); du[s]++;du[e]++; } fa[1]=0;l[1]=0; memset(a,0,sizeof(a)); for (i=1;i<=n;i++) if (du[i]==1) dfs(i,0,1); memset(u,0,sizeof(u)); ans=0ll; for (i=2;i<=nd;i++) ans+=(long long)(l[i]-l[fa[i]]); printf("%lld\n",ans); }
相关文章推荐
- 程序员的量化交易之路(37)--Lean之DataStream数据流5
- 循环赛事日程表
- Cocos2d-3.x_在Lua中使用cjson库解析json
- JSBinding + SharpKit / Home
- SGU 134 Centroid 找树的重心 水题
- 生成1~n的排列,以及生成可重集的排列
- 生成1~n的排列,以及生成可重集的排列
- Leetcode 7 Reverse Integer
- Code First 迁移
- SVN
- BOM的来源是不可能出现的字符,GB2312双字节高位都是1,Unicode理论的根本缺陷导致UTF8的诞生
- CentOS修改SSH端口
- [BZOJ3998]TJOI2015弦论|后缀自动机
- 真机DDMS下data目录打不开——ADB server didn't ACK * failed to start daemon *||Android 查看 /data/data 目录
- 位运算---水题
- @requestparam怎么用
- 紧急情况下压缩了测试周期应该怎么办
- 我的Ubuntu/Linux配置
- C语言中fgetc()函数的返回值意义
- C#程序重启自己