題意: 日本的東西海岸分別有 M, N 座城市,從北至南依次編號,現在東西海岸的某些城市之間修建公路,求所有交點的數量。
題解: 若 a, b 兩公路存在交點的話,必有 a.east < b.east, a. west > b.west 或者 a.east > b.east, a.west < b.west。 對每一條公路的 east 降序排列,east 相同則 west 也按降序排列。這樣一來,只需求 west 的逆序數。用樹狀數組。
#include <algorithm>#include <iostream>using namespace std;#define N 1000005int n, m;__int64 c[N];struct item{int w, e;} node[N];bool cmp ( item x, item y ){if ( x.e != y.e )return x.e > y.e;return x.w > y.w;}int lowbit ( int x ){return x & ( -x );}void update ( int x ){int t = (m > n ? m : n);for ( int i = x; i <= t; i += lowbit(i) )c[i]++;}int getSum ( int x ){int sum = 0;for ( int i = x; i > 0; i -= lowbit(i) )sum += c[i];return sum;}int main(){int t, k, temp, i, test = 0;__int64 ans;scanf("%d",&t);while ( t-- ){ans = 0;memset(c,0,sizeof(c));scanf("%d%d%d",&n,&m,&k);for ( i = 1; i <= k; ++i )scanf("%d%d", &node[i].e, &node[i].w);sort(node+1,node+1+k,cmp); for ( i = 1; i <= k; ++i ){if ( node[i-1].e == node[i].e && node[i-1].w == node[i].w )ans += temp; /* temp 代表前一條公路以其他公路的交點數 */else{ temp = getSum(node[i].w-1);ans += temp;}update(node[i].w);}printf("Test case %d: %I64d\n", ++test, ans);}return 0;}