1. 程式人生 > >【BZOJ2212】【POI2011】Tree Rotations(線段樹合併)

【BZOJ2212】【POI2011】Tree Rotations(線段樹合併)

Description

Solution

對於每個節點有一棵權值線段樹,向上遞迴時合併同時計算逆序對即可。

Source

/************************************************
 * Au: Hany01
 * Date: Mar 22nd, 2018
 * Prob: [BZOJ2122][POI2011] Tree Rotations
 * Email: [email protected]
************************************************/

#include<bits/stdc++.h>
using namespace std; typedef long long LL; typedef pair<int, int> PII; #define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout) #define rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i) #define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i) #define Set(a, b) memset(a, b, sizeof(a)) #define Cpy(a, b) memcpy(a, b, sizeof(a)) #define fir firct #define sec second #define pb(a) push_back(a) #define mp(a, b) make_pair(a, b) #define ALL(a) (a).begin(), (a).end()
#define SZ(a) ((int)(a).size()) #define INF (0x3f3f3f3f) #define INF1 (2139062143) #define Mod (1000000007) #define debug(...) fprintf(stderr, __VA_ARGS__) #define y1 wozenmezhemecaia template <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; } template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; } inline int read() { register int _, __; register char c_; for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1; for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48); return _ * __; } const int maxn = 4000005; int n, lc[maxn * 2], rc[maxn * 2], ret, tr[maxn], cnt; LL cnt1, cnt2, Ans; #define mid ((l + r) >> 1) int build(int l, int r, int x) { int now = ++ cnt; if (l < r) { if (x <= mid) lc[now] = build(l, mid, x); else rc[now] = build(mid + 1, r, x); } tr[now] = 1; return now; } int merge(int x, int y) { if (!x || !y) return x + y; cnt1 += (LL)tr[lc[x]] * (LL)tr[rc[y]], cnt2 += (LL)tr[rc[x]] * (LL)tr[lc[y]]; lc[x] = merge(lc[x], lc[y]), rc[x] = merge(rc[x], rc[y]); tr[x] = tr[lc[x]] + tr[rc[x]]; return x; } int dfs() { register int tmp = read(), x, y, ret; if (tmp) return build(1, n, tmp); x = dfs(), y = dfs(); cnt1 = cnt2 = 0; ret = merge(x, y); Ans += min(cnt1, cnt2); return ret; } int main() { #ifdef hany01 File("bzoj2212"); #endif n = read(); dfs(); printf("%lld\n", Ans); return 0; } //香臉半開嬌旖旎。當庭際。玉人浴出新妝洗。 // -- 李清照《漁家傲·雪裡已知春信至》

相關推薦

BZOJ2212POI2011Tree Rotations線段合併

Description Solution 對於每個節點有一棵權值線段樹,向上遞迴時合併同時計算逆序對即可。 Source /*****************************

[BZOJ2212][Poi2011]Tree Rotations線段合併

Address 洛谷 P3521 BZOJ 2212 LOJ #2163 Solution 非常有意思的題 一個直觀的想法 對於一個點 u

bzoj2333 & luoguP3273棘手的操作線段合併

  題目傳送門:bzoj2333 luoguP3273   這操作還真“棘手”。。聽說這題是可並堆題?然而我不會可並堆。於是我就寫了線段數合併,然後調了一晚上,資料結構毀一生!!!QAQ……   其實這題也可以把合併強行看成樹上的關係然後dfs序後直接線段樹的,然而我菜啊。。看到連邊就只能想到線

uoj#418. 集訓隊作業2018三角形線段合併

傳送門 好迷啊……膜一下ljz 考慮每個操作,如果把操作按先後順序放到序列上的話,操作一就是把\(w_i\)的石子放到某個節點,那麼就是在序列末端加入\(w_i\),然後根據貪心肯定要把它所有兒子的石子拿走,也就是要減去\(\sum w_{son}\) 那麼每個點的答案就是序列的最大字首 因為父親節點

bzoj 2212 : [Poi2011]Tree Rotations 線段合並

sin lse online space 量變 ++ ota hup 左右 題目鏈接:https://www.lydsy.com/JudgeOnline/problem.php?id=2212 思路:用線段樹合並求出交換左右兒子之前之後逆序對的數量,如果數量變小則交換.

HDU1166敵兵佈陣-線段入門

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 127636 &

bzoj4530[Bjoi2014]大融合 並查集+線段合併

線段樹合併好神啊,表示我這種傻逼只能想到樹剖O(nlog^2n)做法 先把原樹建出來,每次查詢就等價於計運算元節點的size*(父親節點所在聯通塊的大小-子節點的size) 用並查集找到節點的祖先,維護子樹size 這個東西可以用線段樹合併來做,查詢就是查詢dfs序上的一段

Poj-A Simple Problem with Integers線段,區間更新

A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 100877 Accepted: 31450 Case Time Limit: 2

BZOJ2212 Poi2011Tree Rotations線段合並

|| 線段樹 merge stdin using add clu ota pac 顯然子樹內的操作不會對子樹外產生影響。於是貪心,若交換之後子樹內逆序對減少就交換。 這個東西可以用權值線段樹計算。操作完畢後需要對兩棵權值線段樹合並,這個的復雜度是兩棵線段樹的重復節點個數。那

hdu-4836-The Query on the Tree線段+LCA

題目連結 思路:對於每次詢問,主要是看x和root的關係,求出root和xlca root=x ,ans為總的和 lca=x  那麼ans=總的和-(root到x這條鏈上父節點為x的那個點的子樹和) 否則,ans就是x的子樹和 求子樹和和修改直接線段樹維護。節點的編

HDU 4836 —— The Query on the Tree線段+LCA

下午百度之星複賽裡最簡單的一題,雖然我還是1個小時才AC的,呃,下午果斷被虐粗翔。 本題磨了1個小時才過,第1題還是很猥瑣地用了隨機數過的(真不知道怎麼做)。 回到這題來,其實也不知道大牛們怎麼做的,我只能用線段樹+LCA搞了。 首先考慮根不改變的情況,那麼我們可以將每個

CSU 1811 Tree Intersection線段+啟發式合併 解法

Problem Reference Meaning 一棵 n 個結點的樹,每個結點都有一種顏色,問對與樹上的每條邊,刪掉它之後得到的兩棵樹中,共有的顏色有多少種(在那兩棵樹中都有的顏色就是公有的顏色) Analysis 首先規定 1 號結點為整棵樹的根(其它號也可

webpack 如何優雅的使用tree-shaking優化

webpack 如何優雅的使用tree-shaking 1.什麼是tree-shaking webpack 2 的到來帶來的最棒的新特性之一就是tree-shaking 。tree-shaking源自於rollup.js,先如今,webpack 2也有類

BZOJ2212Tree RotationsPOI2011-平衡啟發式合併

測試地址:Tree Rotations 做法:本題需要用到平衡樹啟發式合併。 對於葉子節點,最優答案顯然是00。然後對於每棵子樹,我們發現由轉換它的左右子樹所多出的逆序對數,僅和兩邊都有什麼數字有關,而不和兩邊的數字順序有關,所以我們對於每個葉子節點儲存一棵

題解 P3521 [POI2011]ROT-Tree Rotations

新的 eight 寫法 這樣的 完成 個數 col 參考 線段樹 這道題采用權值線段樹合並的解法。 首先講一下解法中出現的兩個概念:權值線段樹與線段樹合並。 所謂權值線段樹,可以理解為維護的信息反過來的普通線段樹,我個人認為值域線段樹這個名字其實要準確一些。

bzoj4605嶗山白花蛇草水 權值線段套KD-tree

復雜 接下來 efi ora 這也 多少 線段樹 會有 如果 題目描述 神犇Aleph在SDOI Round2前立了一個flag:如果進了省隊,就現場直播喝嶗山白花蛇草水。憑借著神犇Aleph的實力,他輕松地進了山東省省隊,現在便是他履行諾言的時候了。蒟蒻Bob特地為他準

BZOJ4605嶗山白花蛇草水 權值線段+kd-tree

現在 ive blog 次數 pan std highlight 解釋 pac 【BZOJ4605】嶗山白花蛇草水 Description 神犇Aleph在SDOI Round2前立了一個flag:如果進了省隊,就現場直播喝嶗山白花蛇草水。憑借著神犇Aleph的實力

bzoj1977[BeiJing2010組隊]次小生成樹 Tree 權值線段合並

for 端點 light 輸出 pan 是否 題目 find upd 題目描述 求一張圖的嚴格次小生成樹的邊權和,保證存在。 輸入 第一行包含兩個整數N 和M,表示無向圖的點數與邊數。 接下來 M行,每行 3個數x y z 表示,點 x 和點y之間有一條邊,邊的權值為

USACO 2004 DEC網絡破壞Tree CuttingDFS

pre nbsp \n printf 整數 back push_back sca 如果 題目描述 約翰意識到貝茜建設網絡花費了他巨額的經費,就把她解雇了.貝茜很憤怒,打算狠狠報 復.她打算破壞剛建成的約翰的網絡. 約翰的網絡是樹形的,連接著N(1≤N≤

連載研究EasyUI系統—Tree元件方法

  前面幾篇文章介紹了tree元件的屬性,接下來我們要介紹tree元件的一些方法。 方法名稱 引數 描述 options 無 獲取元件所有屬性。 loadData data 載入節點資料。 getNo