注意到如果我们用类似 cdq 分治的思想,对于每个节点统计“左子树的叶子和右子树的叶子进行匹配的逆序对数”从而求和得到总体逆序对数,那么对于任意两个不同节点,他们各自的两个子树交不交换位置对答案的影响是互相独立的。
所以只需要求对于每个节点是否交换优即可。
考虑在每个叶节点开权值线段树然后向上合并,合并的过程中我们就能以同样类似 cdq 分治思想的做法,把 逆序对/顺序对 求出来,取最小值加入到答案中即可。
具体求法是,线段树合并的从中间断开递归的时候,算出左区间和右区间匹配出的逆序对,然后再递归下去的时候算左区间和右区间内部的逆序对。
时间复杂度
#include<iostream>
#include<cstdio>
#include<algorithm>
typedef long long ll;
template <typename T> T Max(T x, T y) { return x > y ? x : y; }
template <typename T> T Min(T x, T y) { return x < y ? x : y; }
template <typename T>
T &read(T &r) {
r = 0; bool w = 0; char ch = getchar();
while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
while(ch >= '0' && ch <= '9') r = (r << 3) + (r <<1) + (ch ^ 48), ch = getchar();
return r = w ? -r : r;
}
#define ls(x) tree[x].lson
#define rs(x) tree[x].rson
const int N = 3.8e6;
const int INF = 0x7fffffff;
int n, trnt;
struct SGT {
int lson, rson, sum;
}tree[N];
void modify(int &x, int tl, int tr, int pos) {
if(!x)
x = ++trnt;
++tree[x].sum;
if(tl == tr) return ;
int mid = (tl + tr) >> 1;
if(pos <= mid) modify(ls(x), tl, mid, pos);
else modify(rs(x), mid+1, tr, pos);
}
ll s1, s2, ans;
void merge(int &x, int y, int tl, int tr) {
if(!x || !y) {
x = x + y;
return ;
}
tree[x].sum += tree[y].sum;
if(tl == tr) return ;
s1 += 1ll * tree[rs(x)].sum * tree[ls(y)].sum;
s2 += 1ll * tree[rs(y)].sum * tree[ls(x)].sum;
int mid = (tl + tr) >> 1;
merge(ls(x), ls(y), tl, mid);
merge(rs(x), rs(y), mid+1, tr);
}
void dfs(int &x) {
int t; read(t);
if(!t) {
int lson = 0, rson = 0;
dfs(lson);
dfs(rson);
s1 = 0; s2 = 0;
x = lson; merge(x, rson, 1, n);
ans += Min(s1, s2);
}
else modify(x, 1, n, t);
}
#undef ls
#undef rs
signed main() {
// freopen("in.txt", "r", stdin);
read(n); int root = 0;
dfs(root);
printf("%lld\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?