Codeforces 741D D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 树上启发式合并
2017-11-26 21:16
731 查看
D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Just in case somebody missed it: we have wonderful girls in Arpa’s land.
Arpa has a rooted tree (connected acyclic graph) consisting of n vertices. The vertices are numbered 1through n,
the vertex 1 is the root. There is a letter written on each edge of this tree. Mehrdad is a fan of Dokhtar-kosh things.
He call a string Dokhtar-kosh, if we can shuffle the characters in string such that it becomes palindrome.
He asks Arpa, for each vertex v, what is the length of the longest simple path in subtree of v that
form a Dokhtar-kosh string.
Input
The first line contains integer n (1 ≤ n ≤ 5·105) —
the number of vertices in the tree.
(n - 1) lines follow, the i-th
of them contain an integer pi + 1 and
a letter ci + 1 (1 ≤ pi + 1 ≤ i, ci + 1 is
lowercase English letter, between a and v, inclusively), that mean that there is an edge between
nodes pi + 1 and i + 1 and
there is a letter ci + 1 written
on this edge.
Output
Print n integers. The i-th
of them should be the length of the longest simple path in subtree of the i-th vertex that form a Dokhtar-kosh string.
Examples
input
output
input
output
<
fe3a
span style="font-size:18px;">
一棵树n个点,每条边有一个字母。对于每个点,要求找到它的子树当中最长的一条路径,这条路径上的字符重排之后可以构成回文串。
此题令人疲劳的debug过程说明了,没事就不要在数组清零时的值赋成0或者-1,搞个-inf就可以了。。。
对于每个点,记录这个点到根的路径的每一个字符出现次数的奇偶性,这里用状态压缩存储在数组con[i]里。两个点之间的路径如果满足题目要求,那么必定con[i]=con[j]或者con[i]与con[j]二进制下只有一位不同。先dfs,如果路径不经过当前dfs到的点,可以通过DP得到答案。如果经过,使用树上启发式合并的方法,对每个二进制状态记录此时更新到的最大深度。由于是启发式合并,每个点的重链已经统计过,对于剩下的每条轻链先扫一遍,看里面的点能否和已经扫到的点配对,再更新这条轻链上的点的状态。
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Just in case somebody missed it: we have wonderful girls in Arpa’s land.
Arpa has a rooted tree (connected acyclic graph) consisting of n vertices. The vertices are numbered 1through n,
the vertex 1 is the root. There is a letter written on each edge of this tree. Mehrdad is a fan of Dokhtar-kosh things.
He call a string Dokhtar-kosh, if we can shuffle the characters in string such that it becomes palindrome.
He asks Arpa, for each vertex v, what is the length of the longest simple path in subtree of v that
form a Dokhtar-kosh string.
Input
The first line contains integer n (1 ≤ n ≤ 5·105) —
the number of vertices in the tree.
(n - 1) lines follow, the i-th
of them contain an integer pi + 1 and
a letter ci + 1 (1 ≤ pi + 1 ≤ i, ci + 1 is
lowercase English letter, between a and v, inclusively), that mean that there is an edge between
nodes pi + 1 and i + 1 and
there is a letter ci + 1 written
on this edge.
Output
Print n integers. The i-th
of them should be the length of the longest simple path in subtree of the i-th vertex that form a Dokhtar-kosh string.
Examples
input
4 1 s 2 a 3 s
output
3 1 1 0
input
5 1 a 2 h 1 a 4 h
output
4 1 0 1 0
<
fe3a
span style="font-size:18px;">
一棵树n个点,每条边有一个字母。对于每个点,要求找到它的子树当中最长的一条路径,这条路径上的字符重排之后可以构成回文串。
此题令人疲劳的debug过程说明了,没事就不要在数组清零时的值赋成0或者-1,搞个-inf就可以了。。。
对于每个点,记录这个点到根的路径的每一个字符出现次数的奇偶性,这里用状态压缩存储在数组con[i]里。两个点之间的路径如果满足题目要求,那么必定con[i]=con[j]或者con[i]与con[j]二进制下只有一位不同。先dfs,如果路径不经过当前dfs到的点,可以通过DP得到答案。如果经过,使用树上启发式合并的方法,对每个二进制状态记录此时更新到的最大深度。由于是启发式合并,每个点的重链已经统计过,对于剩下的每条轻链先扫一遍,看里面的点能否和已经扫到的点配对,再更新这条轻链上的点的状态。
#include <cstdio> #include <iostream> #include <string.h> #include <algorithm> #define mem0(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,0x3f,sizeof(a)) using namespace std; typedef long long ll; typedef long double ld; typedef double db; const int maxn=500005,inf=0x3f3f3f3f; const ll llinf=0x3f3f3f3f3f3f3f3f; int head[maxn],size[maxn],son[maxn],ans[maxn]; int con[maxn],dep[maxn]; int mxd[5000005]; bool visit[maxn],big[maxn]; int num=0,tot=0,odd=0; struct Edge { int from,to,pre,dist; }; Edge edge[maxn*2]; void addedge(int from, int to,int dist) { edge[num]=(Edge){from,to,head[from],dist}; head[from]=num++; edge[num]=(Edge){to,from,head[to],dist}; head[to]=num++; } int dfs2(int now,int r,int step) { visit[now]=1;son[now]=-1;size[now]=1; con[now]=r;dep[now]=step; for (int i=head[now];i!=-1;i=edge[i].pre) { int to=edge[i].to; if (!visit[to]) { size[now]+=dfs2(to,r^(1<<edge[i].dist),step+1); if (son[now]==-1||size[to]>size[son[now]]) son[now]=to; } } if (son[now]!=-1) big[son[now]]=1; return size[now]; } int findmax(int now,int fa) { int ans=mxd[con[now]]; for (int i=0;i<22;i++) ans=max(ans,mxd[con[now]^(1<<i)]); if (ans>0) ans+=dep[now]; for (int i=head[now];i!=-1;i=edge[i].pre) { int to=edge[i].to; if (to!=fa&&!big[to]) ans=max(ans,findmax(to,now)); } return ans; } void add(int now,int fa) { mxd[con[now]]=max(mxd[con[now]],dep[now]); for (int i=head[now];i!=-1;i=edge[i].pre) { int to=edge[i].to; if (to!=fa&&!big[to]) add(to,now); } } void eliminate(int now,int fa) { mxd[con[now]]=-inf; for (int i=head[now];i!=-1;i=edge[i].pre) { int to=edge[i].to; if (to!=fa&&!big[to]) eliminate(to,now); } } void dfs(int now,int fa,bool rem) { int mx=0; for (int i=head[now];i!=-1;i=edge[i].pre) { int to=edge[i].to; if (to!=fa&&!big[to]) dfs(to,now,0),mx=max(mx,ans[to]); } if (son[now]!=-1) dfs(son[now],now,1),mx=max(mx,ans[son[now]]); ans[now]=mx; for (int i=head[now];i!=-1;i=edge[i].pre) { int to=edge[i].to; if (to!=fa&&!big[to]) { ans[now]=max(ans[now],findmax(to,now)-2*dep[now]); add(to,now); } } for (int i=0;i<22;i++) ans[now]=max(ans[now],mxd[con[now]^(1<<i)]-dep[now]); ans[now]=max(ans[now],mxd[con[now]]-dep[now]); mxd[con[now]]=max(mxd[con[now]],dep[now]); if (son[now]!=-1) big[son[now]]=0; if (!rem) eliminate(now,fa); } int main() { memset(head,-1,sizeof(head)); int n,i,j,x; char c; scanf("%d",&n); for (i=2;i<=n;i++) { scanf("%d %c",&x,&c); addedge(i,x,c-'a'); } mem0(big);mem0(visit); dfs2(1,0,0); mem0(ans); dfs(1,0,0); for (i=1;i<=n;i++) printf("%d ",ans[i]); return 0; }
相关文章推荐
- [树上启发式合并 && 哈希] Codeforces 741D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
- 【CodeForces】741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
- codeforces 741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths (dsu on the tree)
- CF 741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
- Codeforces 741D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
- 【dsu on tree】Codeforces741D[Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths]题解
- 【题解】codeforces741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
- codeforces741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
- [Codeforces741D]Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on the tree)
- Codeforces 741.D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
- CF 741D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths [dsu on tree 类似点分治]
- codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
- [dsu on tree] Codeforces #741D. Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths
- 【Codeforces 741 B. Arpa's weak amphitheater and Mehrdad's 】+ 并查集 + 01背包
- Codeforces 600E Lomsat gelral [dsu on tree(树上启发式合并)]
- dsu on tree(树上启发式合并)简介(codeforces 600 E)
- Codeforces 842C - Ilya And The Tree 【树上DFS】
- codeforces 711C. Bear and Tree Jumps(树上距离)
- codeforce 741 B. Arpa's weak amphitheater and Mehrdad's valuable Hoses(背包 dp)
- Arpa’s obvious problem and Mehrdad’s terrible solution (CodeForces - 742B)