码迷,mamicode.com
首页 > 其他好文 > 详细

[POJ3067]Japan

时间:2015-09-01 21:33:14      阅读:263      评论:0      收藏:0      [点我收藏+]

标签:

题目链接: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\n", kase++, omega);
96     }
97 }
View Code

 

树状数组:

技术分享
 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\n", kase++, ans);
76     }
77 }
View Code

 

[POJ3067]Japan

标签:

原文地址:http://www.cnblogs.com/vincentX/p/4776715.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!