Japan
题目链接:点击打开链接
解题思路:自己本人也是刚刚接触树状数组,并且也知道树状数组可以求逆序数,但是第一眼还是看不透这个题能用逆序数。
首先,这个题有个规律,凡是能有交叉的线,都有一个规律,两条边A、B,(Ax-By)*(Ay-By)<0;(注意是<没有=,可以自己在直角坐标系中画一下);
然后将x升序排列,x相等的按y升序排列;求y得逆序数,x已经是升序的,y的逆序数必定是降序,所以满足上式子,统计一下总数就是结果;
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define MAXN 100005
using namespace std;
int tree[MAXN];
int n,m,k;
struct Node{
int x,y;
}data[1003*1002];
int cmp(Node a,Node b)
{
if(a.x!=b.x)
return a.x<b.x;
else
return a.y<b.y;
}
void add(int x)
{
for(int i=x;i<=MAXN;i+=i&-i)
tree[i]+=1;
}
int read(int x)
{
int sum=0;
for(int i=x;i>0;i-=i&-i)
sum+=tree[i];
return sum;
}
int main()
{
int t,index=0;
cin>>t;
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<k;i++)
scanf("%d%d",&data[i].x,&data[i].y);//注意这个题如果用cin会超时;
memset(tree,0,sizeof(tree));
sort(data,data+k,cmp);
long long ans=0;
for(int i=0;i<k;i++)
{
add(data[i].y);
ans+=i+1-read(data[i].y);
}
printf("Test case %d: %lld\n",++index,ans);
}
return 0;
}