洛谷 P3521 [POI2011]ROT-Tree Rotations 解题报告
生活随笔
收集整理的這篇文章主要介紹了
洛谷 P3521 [POI2011]ROT-Tree Rotations 解题报告
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
P3521 [POI2011]ROT-Tree Rotations
題意:遞歸給出給一棵\(n(1≤n≤200000)\)個葉子的二叉樹,可以交換每個點的左右子樹,要求前序遍歷葉子的逆序對最少。
大體給出方式:
第一行一個正整數\(n\),表示該二叉樹的葉節點的個數;
下面若干行,每行一個數\(p\):
如果\(p=0\),表示這個節點不是葉節點,遞歸地向下讀入其左孩子和右孩子的信息;
如果\(p \neq 0\) ,表示這個節點是葉節點,權值為\(p\) 。
本來想學一下啟發式合并的,結果被一個很神奇的錯誤卡了很久。。
啟發式合并的復雜度沒怎么學會,只是大致知道權值線段樹的合并和相同的節點數量成正相關,反正把只有一條鏈的權值線段樹都合起來的復雜度是\(O(nlogn)\)的
不過在最后出現了一個神奇的錯誤
10分:
int dfs() {scanf("%d",&k);if(k) return build(1,n,k);s1=s2=0;int now=Merge(dfs(),dfs());ans+=min(s1,s2);return now; }100分:
int dfs() {scanf("%d",&k);if(k) return build(1,n,k);int now=Merge(dfs(),dfs());ans+=min(s1,s2);s1=s2=0;return now; }注意遞歸時賦初值該在什么時候搞
Code:
#include <cstdio> #define ll long long #define ls ch[now][0] #define rs ch[now][1] const int N=200000; ll min(ll x,ll y){return x<y?x:y;} int ch[N*25][2],n,k,tot; ll sum[N*25],ans,s1,s2; int build(int l,int r,int pos) {int now=++tot;sum[now]++;if(l==r) return now;int mid=l+r>>1;if(pos<=mid)ls=build(l,mid,pos);elsers=build(mid+1,r,pos);return now; } int Merge(int x,int y) {if(!x||!y) return x+y;sum[x]+=sum[y];s1+=sum[ch[x][1]]*sum[ch[y][0]];s2+=sum[ch[x][0]]*sum[ch[y][1]];ch[x][0]=Merge(ch[x][0],ch[y][0]);ch[x][1]=Merge(ch[x][1],ch[y][1]);return x; } int dfs() {scanf("%d",&k);if(k) return build(1,n,k);int now=Merge(dfs(),dfs());ans+=min(s1,s2);s1=s2=0;return now; } int main() {scanf("%d",&n);dfs();printf("%lld\n",ans);return 0; }2018.7.30
轉載于:https://www.cnblogs.com/butterflydew/p/9392041.html
總結
以上是生活随笔為你收集整理的洛谷 P3521 [POI2011]ROT-Tree Rotations 解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ 2187 凸包+旋转卡壳
- 下一篇: 算法图解学习笔记01:二分查找大O表示法