Codeforces Round #383 D
傳送門
Description
Arpa has a rooted tree (connected acyclic graph) consisting of n vertices. The vertices are numbered 1 through 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.
題意:一棵根為\(1\) 的樹,每條邊上有一個字符(\(a-v\)共\(22\)種)。 一條簡單路徑被稱為\(Dokhtar-kosh\)當且僅當路徑上的字符經(jīng)過重新排序后可以變成一個回文串。 求每個子樹中最長的\(Dokhtar-kosh\)路徑的長度。
Solution
所求的路徑其實就是只有\(0/1\)個字符出現(xiàn)奇數(shù)次的字符串
發(fā)現(xiàn)最多只有\(22\)種字符,所以可以把一個點到根路徑上字符的出現(xiàn)情況壓成一個二進制數(shù)\(val_i\)
一個數(shù)位\(i\)為\(1\)表示路徑上編號\(i\)的字符出現(xiàn)了奇數(shù)次
所以一條路徑合法等價于\(val_a \ \ xor \ \ val_b=0 \ \ or \ \ 2^i\)
發(fā)現(xiàn)是靜態(tài)的子樹信息維護,可以采用\(dsu\ on \ tree\)
每個點只計算以這個點為\(LCA\)的最長路徑,可以一個一個子樹合并進來
維護一個\(mxdep_i\),表示\(val_x=i\)的最大的\(dep_x\)
對于\(dsu\ on \ tree\):
如果一個關(guān)于子樹集合的詢問滿足
往一個集合里插入一個點是\(O(1)\)的
刪除元素都是到空為止,且每個點的刪除為\(O(1)\)
那么對于這個詢問就可以做到\(O(nlog_2n)\)
因為每個點只會在輕邊處被刪除,因而最多被刪除\(O(log_2n)\)次
Code?
#include<bits/stdc++.h> #define ll long long #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)>(b)?(b):(a)) #define reg register using namespace std; inline int read() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return x*f; } const int MN=5e5+5; struct edge{int to,w,nex;}e[MN]; int n,en,hr[MN]; inline void ins(int x,int y,int w){e[++en]=(edge){y,w,hr[x]};hr[x]=en;} int val[MN],dep[MN],mx[MN],siz[MN]; void dfs1(int x) {siz[x]=1;reg int i;for(i=hr[x];i;i=e[i].nex)val[e[i].to]=val[x]^(1<<e[i].w),dep[e[i].to]=dep[x]+1,dfs1(e[i].to),siz[x]+=siz[e[i].to],(siz[e[i].to]>siz[mx[x]])?mx[x]=e[i].to:0; } #define ri reg int i int cx,mx_dep[1<<22],ans[MN],Dec; void _cal(int x) {if(mx_dep[val[x]]) cx=max(cx,dep[x]+mx_dep[val[x]]-Dec);for(ri=0;i<22;++i)if(mx_dep[val[x]^(1<<i)])cx=max(cx,mx_dep[val[x]^(1<<i)]+dep[x]-Dec); } void _upd(int x){mx_dep[val[x]]=max(dep[x],mx_dep[val[x]]);} void cal(int x){_cal(x);for(ri=hr[x];i;i=e[i].nex)cal(e[i].to);} void upd(int x){_upd(x);for(ri=hr[x];i;i=e[i].nex)upd(e[i].to);} void clr(int x){mx_dep[val[x]]=0;for(ri=hr[x];i;i=e[i].nex)clr(e[i].to);} void dfs2(int x,bool kep=0) {reg int i;for(i=hr[x];i;i=e[i].nex) if(e[i].to!=mx[x]) dfs2(e[i].to);if(mx[x]) dfs2(mx[x],1);Dec=dep[x]<<1;for(i=hr[x];i;i=e[i].nex)cx=max(ans[e[i].to],cx);for(i=hr[x];i;i=e[i].nex)if(e[i].to^mx[x])cal(e[i].to),upd(e[i].to);_cal(x);_upd(x);ans[x]=cx;if(!kep)clr(x),cx=0; } int main() {n=read();reg int i,x;for(i=2;i<=n;++i)x=read(),ins(x,i,getchar()-'a');dfs1(1);dfs2(1);for(i=1;i<=n;++i) printf("%d ",ans[i]);return 0; }Blog來自PaperCloud,未經(jīng)允許,請勿轉(zhuǎn)載,TKS!
轉(zhuǎn)載于:https://www.cnblogs.com/PaperCloud/p/10661183.html
總結(jié)
以上是生活随笔為你收集整理的Codeforces Round #383 D的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 智能计算升级背后:华为“不想再搬砖”
- 下一篇: odoo定时发送邮件