标签:typedef ZJOI int void long inline 2015 眷顾 getchar
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=3926
[算法]
建立广义后缀自动机
对于每个叶子节点 , 以它为根 , 依次将路径上的子串加入自动机
最后统计本质不同的子串个数即可
时间复杂度 : O(N)
[代码]
#include<bits/stdc++.h> using namespace std; const int N = 2e6 + 10; typedef long long ll; typedef long double ld; typedef unsigned long long ull; int n , m; int val[N]; vector< int > a[N]; struct Suffix_Automaton { int size; int father[N << 1] , child[N << 1][15] , depth[N << 1]; Suffix_Automaton() { size = 1; } inline int new_node(int dep) { depth[++size] = dep; memset(child[size] , 0 , sizeof(child[size])); father[size] = 0; return size; } inline int extend(int last , int ch) { int np = child[last][ch]; if (np) { if (depth[np] == depth[last] + 1) return np; else { int nq = new_node(depth[last] + 1); father[nq] = father[np]; father[np] = nq; memcpy(child[nq], child[np], sizeof(child[np])); for (int p = last; child[p][ch] == np; p = father[p]) child[p][ch] = nq; return nq; } } else { np = new_node(depth[last] + 1); int p = last; for (; child[p][ch] == 0; p = father[p]) child[p][ch] = np; if (child[p][ch] == np) { father[np] = 1; return np; } int q = child[p][ch]; if (depth[p] + 1 == depth[q]) { father[np] = q; return np; } else { int nq = new_node(depth[p] + 1); father[nq] = father[q]; father[q] = father[np] = nq; memcpy(child[nq], child[q], sizeof(child[q])); for (; child[p][ch] == q; p = father[p]) child[p][ch] = nq; return np; } } } inline ll calc() { ll ans = 0; for (int i = 2; i <= size; i++) ans += depth[i] - depth[father[i]]; return ans; } } SAM; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline void dfs(int u , int par , int pre) { pre = SAM.extend(pre , val[u]); for (unsigned i = 0; i < a[u].size(); i++) { int v = a[u][i]; if (v != par) dfs(v , u , pre); } } int main() { read(n); read(m); for (int i = 1; i <= n; i++) read(val[i]); for (int i = 1; i < n; i++) { int x , y; read(x); read(y); a[x].push_back(y); a[y].push_back(x); } for (int i = 1; i <= n; i++) if (a[i].size() == 1) dfs(i , 0 , 1); printf("%lld\n" , SAM.calc()); return 0; }
标签:typedef,ZJOI,int,void,long,inline,2015,眷顾,getchar 来源: https://www.cnblogs.com/evenbao/p/10427345.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。