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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 树启 + 状压

發布時間:2023/12/4 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 树启 + 状压 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傳送門

文章目錄

  • 題意:
  • 思路:

題意:

思路:

據說是樹啟的壓軸題。
先觀察題意,字符有1?221-221?22中,為什么不是1?261-261?26個?顯然他就是讓你狀壓的。我們考慮將每條路徑上字符狀壓成statestatestate,讓后從111開始遍歷,記從111iii的路徑上的statestatestatedis[i]dis[i]dis[i]。
再觀察一下回文的性質,回文中奇數個字母最多只有一個,如果兩條路徑能構成回文,那么他們的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。又因為每個狀態有可能有多個depthdepthdepth,讓后我就蠢的對每個狀態開了個multisetmultisetmultiset,先不說內存爆沒爆(我卡了下內存沒爆),復雜度高達O(23nlog2n)O(23nlog^2n)O(23nlog2n),我也不知道我怎么想的,就這么寫了寫交了, 結局也比較顯然,TLEtext10TLE text10TLEtext10了(逃。
顯然這個題可以不用multisetmultisetmultiset,記mx[i]mx[i]mx[i]為狀態是iii的最大深度,根據dsudsudsu的特性,每次我們清空的時候都將mx[i]mx[i]mx[i]重置為000,每次算的時候就貪心的用mx[i]mx[i]mx[i]即可。相信大部分第一反應都是這樣做,但是可能考慮到直接置為000可能會影響到重兒子導致答案錯誤就放棄了這種想法。那么為什么這樣是正確的呢?因為dsudsudsu每次清空的時候都是清空非重兒子的子樹,而且是清空之后才遍歷重兒子,所以不會影響到重兒子的值。還是要對dsudsudsu的遍歷順序理解的比較深刻才能想到。

//#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,mx[(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(mx[y]!=0) ans[rt]=max(ans[rt],depth[u]+mx[y]-2*depth[rt]);for(int i=0;i<22;i++){y=dis[u]^(1<<i);if(mx[y]!=0) ans[rt]=max(ans[rt],depth[u]+mx[y]-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) mx[dis[u]]=max(mx[dis[u]],depth[u]);else mx[dis[u]]=0;for(int i=h[u];~i;i=ne[i]){int x=e[i];if(x==fa) continue;update(x,u,tag);} }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); ans[u]=max(ans[u],ans[x]);}if(son[u]) dfs(son[u],u,1),ans[u]=max(ans[u],ans[son[u]]);if(son[u]){if(mx[dis[u]]) ans[u]=max(ans[u],mx[dis[u]]-depth[u]);for(int i=0;i<22;i++) if(mx[dis[u]^(1<<i)]) ans[u]=max(ans[u],mx[dis[u]^(1<<i)]-depth[u]);}mx[dis[u]]=max(mx[dis[u]],depth[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);}if(!op) update(u,fa,-1); }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);for(int i=1;i<=n;i++) printf("%d ",ans[i]);puts("");return 0; } /**/

貼個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; } /**/

總結

以上是生活随笔為你收集整理的CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 树启 + 状压的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。