题目大意:
给你k条路径,问这些路径有多少个交点;
解题思路:
开始的时候,我把第二个点降序,第一个点升序排列,但是处理了很久仍然wrong,没有办法,只能换网上的求逆序的方法;
我们用(x,y)描述边;
先将第一个x按升序排列,相同的时候则把y按升序排列,然后按照y的位置一边求逆序,一边更新;
为什么这样处理呢?我们已经将x升序排列了,后面要插入的边的x肯定小于等于前面的x,这样的情况下,我们只要统计出前面边的y大于插入边的y即可;
利用树状数组的sum函数,求出小于当前y坐标的边的个数,假设当前要插入第K个数,因为已经插入K-1个,所以直接用K-1-sum(y)即可;
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 1000010
struct Node{
int s,e;
Node(){}
~Node(){}
Node(int a,int b):s(a),e(b){}
bool operator <(const Node &t)const{
if(s!=t.s)
return s<t.s;
else
return e<t.e;
}
};
int n,m;
Node node[maxn];
__int64 c[maxn];
int lowbit(int x)
{
return x&(-x);
}
void updata(int x)
{
while(x<=m)
{
c[x]+=1;
x+=lowbit(x);
}
}
__int64 sum(int x)
{
__int64 ans=0;
while(x>0)
{
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
int test;
scanf("%d",&test);
int tt=1;
while(test--)
{
int k;
memset(c,0,sizeof(c));
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<k;i++)
{
int a,b;
scanf("%d%d",&a,&b);
node[i]=Node(a,b);
}
sort(node,node+k);
__int64 cnt=0;
for(int i=0;i<k;i++)
{
cnt+=i-sum(node[i].e);
updata(node[i].e);
}
printf("Test case %d: %I64d\n",tt++,cnt);
}
}