码迷,mamicode.com
首页 > 其他好文 > 详细

线段树动态开点之逆序对

时间:2019-11-11 12:22:46      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:highlight   cst   一个   数字   逆序   turn   output   sample   个数   

对于给定的一段正整数序列,逆序对就是序列中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;
}

  

线段树动态开点之逆序对

标签:highlight   cst   一个   数字   逆序   turn   output   sample   个数   

原文地址:https://www.cnblogs.com/cutemush/p/11833958.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!