题意:在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;
}