给出N,M,K从N向M连K条边,问有多少个交点?
可以把左边的序列进行从大到小排序,然后求右边的序列中,大于当前值的有多少组,把每组数的满足此条件的个数加起来就是题目要求
直接往后递归可以得出答案O(n^2),但是超时,所以可以用树状数组,每次可以把当前数向上更新,把每个数小于自己的数的个数进行更新
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAX 1010
using namespace std;
long long c[MAX];
long long sum;
int N,M,K;
struct st
{
int x,y;
}sts[MAX*MAX];
bool cmp(st a,st b)
{
if(a.x==b.x)return a.y>b.y;
return a.x>b.x;
}
int lowbit(int x)
{
return x &(-x);
}
void update(int x)
{
while(x<MAX)
{
c[x]++;
x+=lowbit(x);
}
}
long long get(int x)
{
long long sum=0;
while(x>0)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
int ca,cas=1;
scanf("%d",&ca);
while(ca--)
{
scanf("%d%d%d",&N,&M,&K);
memset(c,0,sizeof(c));
memset(sts,0,sizeof(sts));
for(int i=0;i<K;i++)
{scanf("%d%d",&sts[i].x,&sts[i].y);
sts[i].y++;}
sort(sts,sts+K,cmp);
update(sts[0].y);
sum=0;
for(int i=1;i<K;i++)
{
sum+=get(sts[i].y-1);//统计小于y,等价于统计<=y-1
update(sts[i].y);
}
printf("Test case %d: %lld\n",cas++,sum);
}
}

浙公网安备 33010602011771号