CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 树启 + 状压
傳送門
 
文章目錄
- 題意:
- 思路:
題意:
思路:
據(jù)說(shuō)是樹(shù)啟的壓軸題。
 先觀察題意,字符有1?221-221?22中,為什么不是1?261-261?26個(gè)?顯然他就是讓你狀壓的。我們考慮將每條路徑上字符狀壓成statestatestate,讓后從111開(kāi)始遍歷,記從111到iii的路徑上的statestatestate為dis[i]dis[i]dis[i]。
 再觀察一下回文的性質(zhì),回文中奇數(shù)個(gè)字母最多只有一個(gè),如果兩條路徑能構(gòu)成回文,那么他們的dis[i]xordis[j]dis[i] \ \ xor\ \ dis[j]dis[i]??xor??dis[j]最多只有232323種情況,即00...00,10...00,01...00,...,00...0100...00,10...00,01...00,...,00...0100...00,10...00,01...00,...,00...01。那么我們就可以每次都checkcheckcheck一下是否存在dis[j]=dis[i]xor23種情況dis[j]=dis[i]\ \ xor \ \ 23種情況dis[j]=dis[i]??xor??23種情況。又因?yàn)槊總€(gè)狀態(tài)有可能有多個(gè)depthdepthdepth,讓后我就蠢的對(duì)每個(gè)狀態(tài)開(kāi)了個(gè)multisetmultisetmultiset,先不說(shuō)內(nèi)存爆沒(méi)爆(我卡了下內(nèi)存沒(méi)爆),復(fù)雜度高達(dá)O(23nlog2n)O(23nlog^2n)O(23nlog2n),我也不知道我怎么想的,就這么寫(xiě)了寫(xiě)交了, 結(jié)局也比較顯然,TLEtext10TLE text10TLEtext10了(逃。
 顯然這個(gè)題可以不用multisetmultisetmultiset,記mx[i]mx[i]mx[i]為狀態(tài)是iii的最大深度,根據(jù)dsudsudsu的特性,每次我們清空的時(shí)候都將mx[i]mx[i]mx[i]重置為000,每次算的時(shí)候就貪心的用mx[i]mx[i]mx[i]即可。相信大部分第一反應(yīng)都是這樣做,但是可能考慮到直接置為000可能會(huì)影響到重兒子導(dǎo)致答案錯(cuò)誤就放棄了這種想法。那么為什么這樣是正確的呢?因?yàn)?span id="ze8trgl8bvbq"    class="katex--inline">dsudsudsu每次清空的時(shí)候都是清空非重兒子的子樹(shù),而且是清空之后才遍歷重兒子,所以不會(huì)影響到重兒子的值。還是要對(duì)dsudsudsu的遍歷順序理解的比較深刻才能想到。
貼個(gè)TLETLETLE的代碼記錄一下我的蜜汁操作
//#pragma GCC optimize(2) #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<map> #include<cmath> #include<cctype> #include<vector> #include<set> #include<queue> #include<algorithm> #include<sstream> #include<ctime> #include<cstdlib> #define X first #define Y second #define L (u<<1) #define R (u<<1|1) #define pb push_back #define mk make_pair #define Mid (tr[u].l+tr[u].r>>1) #define Len(u) (tr[u].r-tr[u].l+1) #define random(a,b) ((a)+rand()%((b)-(a)+1)) #define db puts("---") using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); } //void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); } //void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII;const int N=500010,M=N*2,mod=1e9+7,INF=0x3f3f3f3f; const double eps=1e-6;int n; int e[M],ne[M],w[M],h[N],idx; int depth[N],son[N],se[N],dis[N]; int ans[N],len; multiset<int>s[(1<<23)];void add(int a,int b,int c) {e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++; }void dfs_son(int u,int fa,int state) {dis[u]=state; se[u]=1;depth[u]=depth[fa]+1;for(int i=h[u];~i;i=ne[i]){int x=e[i];if(x==fa) continue;dfs_son(x,u,state^(1<<w[i]));se[u]+=se[x];if(se[x]>se[son[u]]) son[u]=x;} }void solve(int u,int fa,int rt) {int y=dis[u];if(s[y].size()) len=max(len,depth[u]+(*s[y].rbegin())-2*depth[rt]);for(int i=0;i<22;i++){y=dis[u]^(1<<i);if(s[y].size()) len=max(len,depth[u]+(*s[y].rbegin())-2*depth[rt]);}for(int i=h[u];~i;i=ne[i]){int x=e[i];if(x==fa) continue;solve(x,u,rt);} }void update(int u,int fa,int tag) {if(tag==1) s[dis[u]].insert(depth[u]);else s[dis[u]].erase(s[dis[u]].find(depth[u]));for(int i=h[u];~i;i=ne[i]){int x=e[i];if(x==fa) continue;update(x,u,tag);} }void solve_son(int u,int fa,int rt) {if((dis[u]^dis[rt])==0) len=max(len,depth[u]-depth[rt]);for(int i=0;i<22;i++){int y=dis[u]^(1<<i);if(y!=dis[rt]) continue;len=max(len,depth[u]-depth[rt]);}for(int i=h[u];~i;i=ne[i]){int x=e[i];if(x==fa) continue;solve_son(x,u,rt);} }void dfs(int u,int fa,int op) {for(int i=h[u];~i;i=ne[i]){int x=e[i];if(x==fa||x==son[u]) continue;dfs(x,u,0);}if(son[u]) dfs(son[u],u,1);s[dis[u]].insert(depth[u]);if(son[u]) solve_son(son[u],u,u);for(int i=h[u];~i;i=ne[i]){int x=e[i];if(x==fa||x==son[u]) continue;solve(x,u,u); update(x,u,1);}ans[u]=len; len=0;if(!op) update(u,fa,-1),len=0; }void dfs_ans(int u,int fa) {for(int i=h[u];~i;i=ne[i]){int x=e[i];if(x==fa) continue;dfs_ans(x,u);ans[u]=max(ans[u],ans[x]);} }int main() { // ios::sync_with_stdio(false); // cin.tie(0);scanf("%d",&n); idx=0;memset(h,-1,sizeof(h));for(int i=2;i<=n;i++){int a; char b[2];scanf("%d%s",&a,b);add(a,i,(int)(b[0]-'a'));}dfs_son(1,0,0);dfs(1,0,1);dfs_ans(1,0);for(int i=1;i<=n;i++) printf("%d ",ans[i]);puts("");return 0; } /**/總結(jié)
以上是生活随笔為你收集整理的CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 树启 + 状压的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 香砂仁的功效与作用、禁忌和食用方法
- 下一篇: Codeforces Round #61
