日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces Round #383 D

發(fā)布時間:2025/3/21 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces Round #383 D 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

傳送門

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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。