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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

CodeForces - 1529E Trees of Tranquillity(贪心+线段树)

發布時間:2024/4/11 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 1529E Trees of Tranquillity(贪心+线段树) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:https://vjudge.net/problem/CodeForces-1529E

題目大意:給出兩棵根節點為 111 的樹,分別稱為 AAA 樹和 BBB 樹,現在通過兩棵樹可以構造出一個無向圖,當且僅當點對 (x,y)(x,y)(x,y) 同時滿足以下兩個條件時,可以在圖中建邊:

  • AAA 樹中,xxxyyy 的祖先或 yyyxxx 的祖先
  • BBB 樹中,xxx 不能是 yyy 的祖先同時 yyy 不能是 xxx 的祖先
  • 求該圖的最大團

    題目分析:一開始讀錯題了,后來讀對題后分析的差不多時間也到點了,今天補題的時候發現和賽場的思路差的不算太多,就是一個挺簡單的貪心

    思考一下,滿足最大團的點,在 AAA 樹上和 BBB 樹上的形態是什么樣的,首先這些點在 AAA 樹上一定是一條,從根節點到葉子結點的鏈上的點,可以不連續。在 BBB 樹上就可以體現為,所有點的 dfsdfsdfs 序都沒有交集

    繼續分析,所有點的 dfsdfsdfs 序沒有交集,也就是說需要選擇盡可能多的區間,使其互不相交,這樣就將樹上的問題轉換成線性問題了

    而在 AAA 樹上需要滿足所有的點在同一條鏈上,在 dfsdfsdfs 的時候貪心選擇盡可能多的點就可以了

    然后是題目針對于本題輸入的一個特殊性質,基于給出的樹的輸入方式,是每次給出點 iii 的父節點。這也就使得,AAA 樹和 BBB 樹從根節點拉下來的一條鏈,一定是一個單調遞增的序列,結合于此,針對于 BBB 樹的 dfsdfsdfs 序的區間,有一個下面會用到的性質:

    序號較小的點的區間,要么包含序號較大的點的區間,要么與其不相交

    接下來就可以對 AAAdfsdfsdfs 去貪心了,需要維護一個數據結構,需要實現以下功能:

  • 插入一個區間
  • 刪除一個區間
  • 判斷存在的區間是否存在交集
  • 可以用平衡樹(set),也可以用線段樹,我覺得用線段樹比較好理解,就選擇了線段樹實現

    當遍歷到點 xxx 時,嘗試將點 xxx 所代表的區間插入到線段樹中,無非會出現三種情況:

  • [L[x],R[x]][L[x],R[x]][L[x],R[x]] 中原先并沒有區間,則直接插入即可
  • [L[x],R[x]][L[x],R[x]][L[x],R[x]] 被一個更大的區間覆蓋,則將其刪掉,并替換上點 xxx 所代表的區間顯然更優
  • [L[x],R[x]][L[x],R[x]][L[x],R[x]] 中包含了大于一個區間,此時如果想加入 xxx 所代表的區間,就需要將沖突的區間全都刪掉,顯然舍棄掉 xxx 所代表的區間是更優的,實際操作就是,無需操作
  • 回溯的時候將 xxx 所代表的區間按照上述三種情況還原即可

    最后的最后還有一個比較難解決的小問題,就是,如何快速查詢區間 [L[x],R[x]][L[x],R[x]][L[x],R[x]] 中存在的不同區間的個數,以及如何快速更新線段樹

    還記得前面加粗的性質嗎?序號大小這個條件還沒有用上呢

    其實我們可以直接去查詢 [L[x],R[x]][L[x],R[x]][L[x],R[x]] 中,存在的區間的最大編號即可,因為在 AAA 樹上 dfsdfsdfs 遍歷的鏈也是遞增遍歷的,結合加粗的性質,如果 [L[x],R[x]][L[x],R[x]][L[x],R[x]] 之前被覆蓋過,那么一定是一個更大的區間覆蓋的,所以上述的三種情況里,第三種情況實際上根本不可能出現

    代碼:

    // Problem: E. Trees of Tranquillity // Contest: Codeforces - Codeforces Round #722 (Div. 2) // URL: https://codeforces.com/contest/1529/problem/E // Memory Limit: 256 MB // Time Limit: 3000 ms // // Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<list> #include<unordered_map> #define lowbit(x) x&-x using namespace std; typedef long long LL; typedef unsigned long long ull; template<typename T> inline void read(T &x) {T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f; } template<typename T> inline void write(T x) {if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0'); } const int inf=0x3f3f3f3f; const int N=1e6+100; vector<int>a[N],b[N]; int L[N],R[N],dfn,sum,ans; struct Node {int l,r,mmax,lazy; }tree[N<<2]; void pushup(int k) {tree[k].mmax=max(tree[k<<1].mmax,tree[k<<1|1].mmax); } void pushdown(int k) {if(tree[k].lazy!=-1) {int lz=tree[k].lazy;tree[k].lazy=-1;tree[k<<1].mmax=tree[k<<1|1].mmax=lz;tree[k<<1].lazy=tree[k<<1|1].lazy=lz;} } void build(int k,int l,int r) {tree[k]={l,r,0,-1};if(l==r) {return;}int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r); } void update(int k,int l,int r,int val) {if(tree[k].l>r||tree[k].r<l) {return;}if(tree[k].l>=l&&tree[k].r<=r) {tree[k].mmax=tree[k].lazy=val;return;}pushdown(k);update(k<<1,l,r,val);update(k<<1|1,l,r,val);pushup(k); } int query(int k,int l,int r) {if(tree[k].l>r||tree[k].r<l) {return 0;}if(tree[k].l>=l&&tree[k].r<=r) {return tree[k].mmax;}pushdown(k);return max(query(k<<1,l,r),query(k<<1|1,l,r)); } void dfs1(int u) {L[u]=++dfn;for(auto v:b[u]) {dfs1(v);}R[u]=dfn; } void dfs2(int u) {int mmax=query(1,L[u],R[u]);if(!mmax) {update(1,L[u],R[u],u);sum++;} else {update(1,L[mmax],R[mmax],0);update(1,L[u],R[u],u);}ans=max(ans,sum);for(auto v:a[u]) {dfs2(v);}if(!mmax) {update(1,L[u],R[u],0);sum--;} else {update(1,L[u],R[u],0);update(1,L[mmax],R[mmax],mmax);} } int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int w;cin>>w;while(w--) {int n;read(n);dfn=0;for(int i=1;i<=n;i++) {a[i].clear();b[i].clear();}for(int i=2;i<=n;i++) {int fa;read(fa);a[fa].push_back(i);}for(int i=2;i<=n;i++) {int fa;read(fa);b[fa].push_back(i);}dfn=ans=sum=0;build(1,1,n);dfs1(1);dfs2(1);cout<<ans<<endl;}return 0; }

    總結

    以上是生活随笔為你收集整理的CodeForces - 1529E Trees of Tranquillity(贪心+线段树)的全部內容,希望文章能夠幫你解決所遇到的問題。

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