luoguP3521 [POI2011]ROT-Tree Rotations【线段树】
你要写热,就不能只写热。
要写酷暑,写骄阳,写他人耳闻便生恐的炙烤和炎灼。
要写白日出门一刻便肤色黝黑,背心透彻。
写求雨心切,写出行伞遮。
写夜晚不停的风扇和蝉聒。
写鸡蛋落地便熟,流水转眼耗涸。
再写千家万户空调响,西瓜冰可乐。
直至最后,才猛然起身,把浑身上下的黏腻腻,涓涓水冲落。
--所以某校友会rank第五高校为什么8月18开学还军训,武汉都四十度了,又等着芊芊学子知乎治校吗???
哎,我太多伤春悲秋都来源于我的迷茫踯躅。年轻人是无法同时拥有青春和对青春的感受,一段往事结束的标志就是她开始被浪漫化的时候。当年陪我看日落的人,比日落本身更温柔,除了风,没有谁知道日落大道上的出逃。不知是和你一起看喜欢的晚霞,还是和晚霞一起看喜欢的人。什么时候,人的主观能动性会被客观条件锁死?至少统计逆序对时,只有左子树,右子树,两树交叉三种情况,前两种递归即可,关键是最后一种需要讨论改变与否,分别比较后择优。有个记不起名字的女孩曾写道,“温柔与浪漫是人间宝藏”,她精心准备的本子我现在还留着,明明接到礼物时那么开心,却忘却了她的名字,记不得名字的人脸庞也会逐渐模糊,为什么要强装矜持呢,为什么不能把惊喜与感谢传达出去呢?总是这样,后知后觉的吧。
那个本子肯定不会带去学校的,等着多年后翻看哀哀啼啼感时葬花独伤秋吧。
I don't wanna go to school ahahahah
# include "bits/stdc++.h"
using namespace std;
int main() {
int n;
cin >> n;
long long answer_without_exchange, answer_after_exchange;
struct node {
int l, r, siz;
};
# define ls t[rt].l
# define rs t[rt].r
# define lson t[rt].l, l, mid
# define rson t[rt].r, mid + 1, r
vector<node> t((n + 1) * (log(n + 1) + 1) * 2); // seriously, there should * 2
auto push_up = [&](int rt) -> void {
t[rt].siz = t[ls].siz + t[rs].siz;
};
int tree_index = 0;
vector<int> rt(n + 1);
auto update = [&](auto update, int rt, int l, int r, int x) -> int {
t[rt].siz = 1; // first set the size of all nodes to 1, ensuring the validity of the multiplication operation in the subsequent anwer statistics
if(l == r) {
// t[rt].siz = 1;
return rt;
}
int mid = l + r >> 1;
if(x <= mid)
t[rt].l = update(update, ++tree_index, l, mid, x);
else
t[rt].r = update(update, ++tree_index, mid + 1, r, x);
return rt;
};
auto merge = [&](auto merge, int x, int y, int l, int r) -> int {
if(!x || !y) return x | y;
if(l == r) {
t[x].siz += t[y].siz;
return x;
}
answer_without_exchange += 1ll * t[t[x].l].siz * t[t[y].r].siz;
answer_after_exchange += 1ll * t[t[x].r].siz * t[t[y].l].siz;
int mid = l + r >> 1;
t[x].l = merge(merge, t[x].l, t[y].l, l, mid);
t[x].r = merge(merge, t[x].r, t[y].r, mid + 1, r);
push_up(x);
return x;
};
long long ans = 0;
auto dfs = [&](auto dfs) -> int {
int now, val;
cin >> val;
if(val == 0) {
int left_subtree = dfs(dfs), right_subtree = dfs(dfs); // preorder traversal
answer_without_exchange = 0;
answer_after_exchange = 0;
now = merge(merge, left_subtree, right_subtree, 1, n);
ans += min(answer_without_exchange, answer_after_exchange);
}
else {
now = update(update, ++tree_index, 1, n, val);
}
return now;
};
dfs(dfs);
cout << ans;
return 0;
}