题目链接:http://poj.org/problem?id=3067
线段树和树状数组都可以做。
线段树:
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 #include <iostream> 6 #include <cmath> 7 #include <queue> 8 #include <map> 9 #include <stack> 10 #include <list> 11 #include <vector> 12 13 using namespace std; 14 15 const int maxn = 3000010; 16 17 typedef long long LL; 18 typedef struct Node { 19 int x; 20 int y; 21 }; 22 23 Node node[maxn]; 24 int sum[maxn]; 25 int num[maxn]; 26 27 inline bool cmp(Node a, Node b) { 28 if(a.y != b.y) { 29 return a.y > b.y; 30 } 31 return a.x < b.x; 32 } 33 34 void update(int left, int right, int rt, int x) { 35 if(left == right) { 36 sum[rt]++; 37 num[left]++; 38 return ; 39 } 40 int mid = (left + right) >> 1; 41 if(x <= mid) { 42 update(left, mid, rt<<1, x); 43 } 44 else { 45 update(mid+1, right, rt<<1|1, x); 46 } 47 sum[rt] = sum[rt<<1] + sum[rt<<1|1]; 48 } 49 50 int query(int left, int right, int L, int R, int rt) { 51 if(L <= left && R >= right) { 52 return sum[rt]; 53 } 54 int mid = (left + right) >> 1; 55 int ans = 0; 56 if(L <= mid) { 57 ans += query(left, mid, L, R, rt<<1); 58 } 59 if(R > mid) { 60 ans += query(mid+1, right, L, R, rt<<1|1); 61 } 62 return ans; 63 } 64 65 int n, m, k; 66 int res; 67 LL omega; 68 69 int main() { 70 // freopen("in", "r", stdin); 71 int kase = 1; 72 int T; 73 scanf("%d", &T); 74 while(T--) { 75 memset(sum, 0, sizeof(sum)); 76 memset(num, 0, sizeof(num)); 77 res = 0; 78 omega = 0; 79 scanf("%d %d %d", &n, &m, &k); 80 for(int i = 1; i <= k; i++) { 81 scanf("%d %d", &node[i].x, &node[i].y); 82 } 83 sort(node+1, node+k+1, cmp); 84 for(int i = 1; i <= k; i++) { 85 int tmp = node[i].y; 86 if(i > 1 && node[i].y == node[i-1].y) { 87 res++; 88 } 89 else { 90 res = 0; 91 } 92 omega += query(1, n, 1, node[i].x, 1) - num[node[i].x] - res; 93 update(1, n, 1, node[i].x); 94 } 95 printf("Test case %d: %I64d ", kase++, omega); 96 } 97 }
树状数组:
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 #include <iostream> 6 #include <cmath> 7 #include <queue> 8 #include <map> 9 #include <stack> 10 #include <list> 11 #include <vector> 12 13 using namespace std; 14 15 const int maxn = 1000010; 16 typedef long long LL; 17 typedef struct Node { 18 LL x; 19 LL y; 20 }; 21 22 Node node[maxn]; 23 LL d[maxn<<1]; 24 LL n, m, k; 25 LL ans; 26 27 inline bool cmp(Node a, Node b) { 28 if(a.x != b.x) { 29 return a.x > b.x; 30 } 31 return a.y > b.y; 32 } 33 34 //求某点管辖范围 35 LL lowbit(LL x) { //求x末尾最低位1的位置(末尾0的个数+1) 36 // return x & (x ^ (x - 1)); 37 return x & (-x); 38 } 39 40 //区间更新树状数组(i到x) 41 void update(LL i, LL x, LL num) { 42 while(i <= x) { 43 d[i] += num; 44 i += lowbit(i); 45 } 46 } 47 48 //获取前x项和 49 LL getsum(LL x) { 50 LL sum = 0; 51 while(x > 0) { 52 sum += d[x]; 53 x -= lowbit(x); 54 } 55 return sum; 56 } 57 58 int main() { 59 // freopen("in", "r", stdin); 60 LL kase = 1; 61 LL T; 62 scanf("%I64d", &T); 63 while(T--) { 64 memset(d, 0, sizeof(d)); 65 scanf("%I64d %I64d %I64d", &n, &m, &k); 66 for(LL i = 1; i <= k; i++) { 67 scanf("%I64d %I64d", &node[i].x, &node[i].y); 68 } 69 sort(node+1, node+k+1, cmp); 70 ans = 0; 71 for(int i = 1; i <= k; i++) { 72 ans += getsum(node[i].y-1); 73 update(node[i].y, m, 1); 74 } 75 printf("Test case %I64d: %I64d ", kase++, ans); 76 } 77 }