给出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); } }