• [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
  • 相关阅读:
    Google Authentication 机制原理
    ldap日志
    ldap + kerberos 整合
    kerberos
    U盘格式化后的恢复
    初始化脚本(Os_Init_Optimization.sh)
    拿到新机器,进行初始化和部署Nginx的过程
    python 列表生成式
    python 装饰器
    简单总结无线CPE、无线AP、无线网桥的不同之处【转】
  • 原文地址:https://www.cnblogs.com/kirai/p/4776715.html
Copyright © 2020-2023  润新知