zoukankan      html  css  js  c++  java
  • [POJ3067]Japan

    题目链接: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 }
    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
    ", kase++, ans);
    76     }
    77 }
    View Code
  • 相关阅读:
    896. Monotonic Array单调数组
    865. Smallest Subtree with all the Deepest Nodes 有最深节点的最小子树
    489. Robot Room Cleaner扫地机器人
    JavaFX
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
  • 原文地址:https://www.cnblogs.com/kirai/p/4776715.html
Copyright © 2011-2022 走看看