这题关键就在于如何才算相交,要求应该是n比上一个大,m比上一个小,我们可以先将所有数据按照从n的从小到大,再从m的从小到大,这样同一个点出发的会依次增加上去,这样新增加的点与其他线的交点数就是在这点之后的所有的点的值的和,我们用两个sum一减就行。(语言表达不行,你们可以直接看代码....)
坑点在于为什么要用__int64?可以想象一下极限的情况,第一个点把所有的都连了的话第二个点就是999加到1,第三个点就是1998加到1,这样加到最后就是999*999再加到1;所以得用__int64;
#include <stdio.h>
#include<algorithm>
#include <string.h>
using namespace std;
__int64 c[1000+10];
int n;
struct node
{
int st,en;
}road[1000000+10];
int cmp(node x,node y)
{
if(x.st!=y.st)
return x.st<y.st;
else
return x.en<y.en;
}
int lowbit(int k)
{
return (k&(-k));
}
int sum(int x) //求和
{
__int64 ret = 0;
while(x>0)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
void add(int x,int d) //修改节点的值
{
while(x<=n)
{
c[x]+=d;
x+=lowbit(x);
}
}
int main()
{
int t;
scanf("%d",&t);
int icase;
for(icase=1;icase<=t;icase++)
{
memset(c,0,sizeof(c));
int n1,m1,k;
scanf("%d%d%d",&n1,&m1,&k);
int i,j;
n=m1;
__int64 ans=0;
for(i=0;i<k;i++)
{
scanf("%d%d",&road[i].st,&road[i].en);
}
sort(road,road+k,cmp);
for(i=0;i<k;i++)
{
ans+=sum(m1)-sum(road[i].en);
add(road[i].en,1);
}
printf("Test case %d: %I64d\n",icase,ans);
}
return 0;
}