题意:
左边有N个点,右边有M个点,有K个连线,问相交点数有多少个。
思路:
左边的点从小到大排序,然后和右边的点如果相连的点在该点的下方有相连的线段则必与该线段相交。
就转换为求区间i—m连接点的个数和问题。
直接树状数组。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<string>
#include<map>
using namespace std;
typedef long long int ll;
const int N=1000000+10;
const int MAX=1000000+8;
int bit[N];
struct node
{
int x,y;
bool operator <(const node &m)const
{
if(x!=m.x)
return x<m.x;
else
return y<m.y;
}
}P[N];
int lowbit(int x)
{
return x&-x;
}
void add(int x)
{
while(x<=MAX)
{
bit[x]++;
x+=lowbit(x);
}
}
ll sum(int x)
{
ll ans=0;
while(x)
{
ans+=bit[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
int t,ca=1;
scanf("%d",&t);
while(t--)
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
memset(bit,0,sizeof(bit));
for(int i=0;i<k;i++)
{
scanf("%d%d",&P[i].x,&P[i].y);
}
sort(P,P+k);
ll ans=0;
for(int i=0;i<k;i++)
{
ans+=sum(m)-sum(P[i].y);
add(P[i].y);
}
printf("Test case %d: %lld\n",ca++,ans);
}
return 0;
}