线段树动态开点之逆序对

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;
}

  

以上是关于线段树动态开点之逆序对的主要内容,如果未能解决你的问题,请参考以下文章

[CQOI2011]动态逆序对

题解-P3157 [CQOI2011]动态逆序对

HDU6183 Color it (线段树动态开点)

#RMQ,动态开点线段树#CF803G Periodic RMQ Problem

动态开点线段树

动态开点线段树