[Codeforces741D]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——dsu on tree
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:
Codeforces741D
題目大意:給出一棵樹,根為$1$,每條邊有一個$a-v$的小寫字母,求每個點子樹中的一條最長的簡單路徑使得這條路徑上的邊上的字母重排后是一個回文串。
顯然如果一條路徑上的字母重排后是回文串,那么最多有一個字母有奇數個。我們用$2^{22}$的一個二進制來記錄有哪些字母有奇數個。剩下的只需要$dsu\ on\ tree$來求每個點的答案即可。對于每個點記錄它到根的路徑上的字母的二進制狀態,顯然位于一個點兩個不同子樹中的點的狀態異或起來就是這兩個點間路徑的二進制狀態。開一個桶存每種狀態的最大深度然后在對于每個點求答案時依次遍歷子樹求出最大值即可。注意遍歷輕兒子時要先用輕兒子子樹中的點更新答案之后再將輕兒子子樹中的點的信息加入桶中。
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<bitset> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; int cnt[5000000]; int head[500010]; int to[1000010]; int nex[1000010]; int size[500010]; int son[500010]; int val[500010]; int dep[500010]; int tot; int n; int x,y; char ch[2]; int ans[500010]; int tag[500010]; void add(int x,int y) {nex[++tot]=head[x];head[x]=tot;to[tot]=y; } void dfs(int x) {size[x]=1;for(int i=head[x];i;i=nex[i]){dep[to[i]]=dep[x]+1;val[to[i]]^=val[x];dfs(to[i]);size[x]+=size[to[i]];if(size[to[i]]>size[son[x]]){son[x]=to[i];}} } void calc(int x,int anc) {ans[anc]=max(ans[anc],cnt[val[x]]+dep[x]-2*dep[anc]);for(int i=0;i<22;i++){ans[anc]=max(ans[anc],cnt[val[x]^(1<<i)]+dep[x]-2*dep[anc]);}for(int i=head[x];i;i=nex[i]){calc(to[i],anc);} } void solve(int x,int opt) {if(opt==1){cnt[val[x]]=max(dep[x],cnt[val[x]]);}else{cnt[val[x]]=-1<<30;}for(int i=head[x];i;i=nex[i]){solve(to[i],opt);} } void dsu_on_tree(int x,int opt) {for(int i=head[x];i;i=nex[i]){if(to[i]!=son[x]){dsu_on_tree(to[i],0);ans[x]=max(ans[x],ans[to[i]]);}}if(son[x]){dsu_on_tree(son[x],1);ans[x]=max(ans[x],ans[son[x]]);}cnt[val[x]]=max(cnt[val[x]],dep[x]);ans[x]=max(ans[x],cnt[val[x]]-dep[x]);for(int i=0;i<22;i++){ans[x]=max(ans[x],cnt[val[x]^(1<<i)]-dep[x]);}for(int i=head[x];i;i=nex[i]){if(to[i]!=son[x]){calc(to[i],x);solve(to[i],1);}}if(!opt){solve(x,-1);} } int main() {scanf("%d",&n);for(int i=2;i<=n;i++){scanf("%d%s",&x,ch);add(x,i);val[i]=1<<(ch[0]-'a');}dfs(1);for(int i=0;i<=(1<<22);i++){cnt[i]=-1<<30;}dsu_on_tree(1,1);for(int i=1;i<=n;i++){printf("%d ",ans[i]);} }轉載于:https://www.cnblogs.com/Khada-Jhin/p/10645756.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的[Codeforces741D]Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths——dsu on tree的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: react --- 搭建环境
- 下一篇: 一分钟检测应用状态 | 企业应用健康扫描