【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;
}
//香臉半開嬌旖旎。當庭際。玉人浴出新妝洗。
// -- 李清照《漁家傲·雪裡已知春信至》
相關推薦
【BZOJ2212】【POI2011】Tree 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 思路:用線段樹合並求出交換左右兒子之前之後逆序對的數量,如果數量變小則交換.
【HDU】1166敵兵佈陣-(線段樹入門)
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也有類
【BZOJ2212】Tree Rotations(POI2011)-平衡樹啟發式合併
測試地址: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 Cutting(DFS)
pre nbsp \n printf 整數 back push_back sca 如果 題目描述 約翰意識到貝茜建設網絡花費了他巨額的經費,就把她解雇了.貝茜很憤怒,打算狠狠報 復.她打算破壞剛建成的約翰的網絡. 約翰的網絡是樹形的,連接著N(1≤N≤
【連載】研究EasyUI系統—Tree元件(方法)
前面幾篇文章介紹了tree元件的屬性,接下來我們要介紹tree元件的一些方法。 方法名稱 引數 描述 options 無 獲取元件所有屬性。 loadData data 載入節點資料。 getNo