题意:在Japan的东西两边都有海岸线。两边分别有n,m个城市,他们的编号分别都为1....n, 1....m。要在东西海岸的城市间建立一些高速路,通过点对给出。求所有的交点有多少个(一个交点保证只有两条路穿过)。
思路:树状数组。具体来说,如果把1...m重新从大到小编号(具体的操作可以用m+1减去原来编号)。则问题变成求一对儿的x和y完全大于另一对儿的对数。这与苹果那题便如出一辙。将(n,m)按照m从小到大排序,相同的按照n从大到小,查找sum(n-1)即可。
#include <stdio.h> #include <string.h> #include <stdlib.h> #define N 1010 struct node{ int x,y; }p[N*N]; __int64 tree[N]; int T,c=0; int n,m,k; int cmp(const struct node *a,const struct node *b){ if((*a).y == (*b).y) return (*b).x - (*a).x; return (*a).y - (*b).y; } int lowbit(int x){ return x&(-x); } void add(int x){ int i; for(i = x;i<=n;i+=lowbit(i)) tree[i]++; } __int64 sum(int x){ int i; __int64 res=0; for(i = x;i>=1;i-=lowbit(i)) res += tree[i]; return res; } int main(){ freopen("a.txt","r",stdin); scanf("%d",&T); while(c++<T){ int i,a,b; __int64 res=0; memset(tree,0,sizeof(tree)); scanf("%d %d %d",&n,&m,&k); for(i = 0;i<k;i++){ scanf("%d %d",&a,&b); p[i].x = a; p[i].y = m+1-b; } qsort(p,k,sizeof(struct node),cmp); for(i = 0;i<k;i++){ res += sum(p[i].x-1); add(p[i].x); } printf("Test case %d: %I64d\n",c,res); } return 0; }