题意叫你求交叉点的个数,转换一下思维,把第一个数看作是i,和它相连接的第二个数看作是ai,当i < j 且 ai > aj时这时才有交叉点,
这样就转换为求逆序对的个数;首先,把他x从小到大排序,x相同的按y从大到小排序,排完序后,在使用合并排序,计算逆序对的个数。


1 #include<stdio.h>//从网上搜的都是用树状数组解的,这个我暂时还不会,等以后学了在看吧。 2 #include<stdlib.h> 3 #define MAX 1000005 4 5 typedef struct NODE 6 { 7 int x,y; 8 }Node; 9 10 Node p[MAX]; 11 long long count; 12 13 void Mergerarray(int first, int mid, int last) 14 { 15 int i,j,k; 16 int n1 = mid - first + 1; 17 int n2 = last - mid; 18 int L[n1+1],R[n2+1]; 19 20 for(i=0; i<n1; i++) 21 L[i] = p[first + i].y; 22 for(j=0; j<n2; j++) 23 R[j] = p[mid + 1 + j].y; 24 25 i = j = 0; 26 L[n1] = 2100000000; 27 R[n2] = 2100000000; 28 for(k = first; k <= last; k++) 29 { 30 if(L[i] <= R[j]) 31 { 32 p[k].y = L[i++]; 33 } 34 else 35 { 36 count += (long long)(n1-i); 37 p[k].y = R[j++]; 38 } 39 } 40 41 } 42 43 void Mergersort(int first, int last) 44 { 45 int mid; 46 47 if(first < last) 48 { 49 mid = (first + last)/2; 50 Mergersort(first, mid); 51 Mergersort(mid+1, last); 52 Mergerarray(first, mid, last); 53 } 54 } 55 56 int cmp(const void *a, const void *b) 57 { 58 if(((Node *)a)->x > ((Node *)b)->x) 59 return 1; 60 else if((((Node *)a)->x ==((Node *)b)->x) && (((Node *)a)->y > ((Node *)b)->y)) 61 return 1; 62 return -1; 63 } 64 65 int main() 66 { 67 int i,j,ncases; 68 int N,M,K; 69 70 scanf("%d",&ncases); 71 for(i=1; i<=ncases; i++) 72 { 73 scanf("%d%d%d",&N,&M,&K); 74 for(j=0; j<K; j++) 75 scanf("%d%d",&p[j].x,&p[j].y); 76 qsort(p, K, sizeof(Node), cmp); 77 count = 0LL; 78 79 Mergersort(0,K-1); 80 printf("Test case %d: %lld\n", i, count); 81 } 82 system("pause"); 83 return 0; 84 }