线段树动态开点之逆序对
Posted cutemush
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树动态开点之逆序对相关的知识,希望对你有一定的参考价值。
对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对。
求这段正整数序列中逆序对的数目。
Input
第一行,一个数n,表示序列中有n个数。N<=5*10^5
第二行n个数,表示给定的序列。序列中每个数字不超过10^9
Output
给定序列中逆序对的数目。
Sample Input
6
5 4 2 6 3 1
Sample Output
11
#include<cstdio> #define ll long long using namespace std; const int N=1e7+7; int n,r; ll ans; struct A { int cnt,c[N],lc[N],rc[N]; int sum(int p,int l,int r,int x,int y) { if(!p) return 0; if(l==x&&r==y) return c[p]; int mid=l+r>>1; if(y<=mid) return sum(lc[p],l,mid,x,y); if(x>mid) return sum(rc[p],mid+1,r,x,y); return sum(lc[p],l,mid,x,mid)+sum(rc[p],mid+1,r,mid+1,y); } void add(int &p,int l,int r,int x,int k) { if(!p) p=++cnt; if(l==r) { c[p]+=k; return; } int mid=l+r>>1; if(x<=mid) add(lc[p],l,mid,x,k); else add(rc[p],mid+1,r,x,k); c[p]=c[lc[p]]+c[rc[p]]; } }tree; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); ans+=tree.sum(r,1,1e9,x+1,1e9); tree.add(r,1,1e9,x,1); } printf("%lld",ans); return 0; }
以上是关于线段树动态开点之逆序对的主要内容,如果未能解决你的问题,请参考以下文章