第2 - N + 1行:N个点的坐标,坐标为整数。(0 <= X i , Y i <= 10^9)
4 2 3 3 4 1 5 4 6
2
运用树状数组和逆序数比较容易想到
一道关于树状数组和逆序数的题跟这个很像——
Ultra-QuickSort
在求逆序数时2 3 2 4这种情况没问题 但是2 4 2 3 就要判断一下
还有个问题是离散化
原来用的方法不适用于有重复元素的 这个是新找到的~~~~~~~
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include <bits/stdc++.h>
using namespace std;
const int maxn=50010;
int c[maxn];
int x[maxn],data[maxn];
int n;
struct node
{
int x,y;
}a[maxn];
int cmp1(node a,node b)
{
return a.x<b.x;
}
int lowbit(int i)
{
return i&(-i);
}
int update(int i,int x)
{
while(i<=maxn)
{
c[i]=c[i]+x;
i=i+lowbit(i);
}
}
int query(int i)
{
int sum=0;
while(i>0)
{
sum+=c[i];
i=i-lowbit(i);
}
return sum;
}
void prepare() {
int i;
for(int i=1;i<=n;i++)
data[i]=a[i].y;
sort(data+1,data+n+1);
int m=unique(data+1,data+n+1)-data-1;
for(int i=1;i<=n;i++) a[i].y=lower_bound(data+1,data+m+1,a[i].y)-data;
}
int main()
{
while(cin>>n)
{
memset(c,0,sizeof(c));
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
prepare();
sort(a+1,a+n+1,cmp1);
long long sum=0;
for(int i=1;i<=n;i++)
{
update(a[i].y,1);
sum+=i-query(a[i].y);
if(a[i-1].x==a[i].x&&i!=1&&a[i-1].y>a[i].y)
sum--;
}
cout<<sum<<endl;
}
return 0;
}