zoukankan      html  css  js  c++  java
  • 树状数组求逆序对

    我果然还是太NAIVE了

    一直没有学到这么搞基的求逆序对数方法

    其实就是有点像计数排序

    先开一个巨大的树状数组

    然后插入一个数的时候看一下SUM

    用当前位置减一下SUM就可以了

    //其实就是求和

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <cmath>
     7 using namespace std;
     8 long long read() {
     9     long long x = 0, f = 1; char ch = getchar();
    10     while (!isdigit(ch)) {
    11         if (ch == '-') f = -1; ch = getchar();
    12     }
    13     while (isdigit(ch)) {
    14         x = x * 10 + ch - '0'; ch = getchar();
    15     }
    16     return x * f;
    17 }
    18 
    19 /*------------------------------template------------------------------*/
    20 
    21 #define nxt(x) (x & -x)
    22 #define M 500050
    23 typedef pair<int, int> pr;
    24 int a[M << 1];
    25 long long ans = 0;
    26 int c[M], b[M];
    27 int main () {
    28     int n = read(), x;
    29         memset(c, 0, sizeof(c));
    30         memset(a, 0, sizeof(a));
    31         for (int i = 1; i <= n; i ++) {
    32             b[i] = c[i] = read();
    33         }
    34         sort(b + 1, b + 1 + n);
    35         int tot = unique(b + 1, b + 1 + n) - b;
    36         for (int i = 1; i <= n; i ++) {
    37             c[i] = lower_bound(b + 1, b + tot, c[i]) - b;
    38         }
    39         for (int i = 1; i <= n; ans += i ++) {
    40             x = c[i];
    41             for (int j = x; j <= n; j += nxt(j)) {
    42                 a[j] ++;
    43             }
    44             for (int j = x; j > 0; j -= nxt(j)) {
    45                 ans -= a[j];
    46             }
    47             //printf("%d %d %d
    ", x, i, ans);
    48         }
    49         printf("%lld
    ", ans); //打成%d调了半天23333333
    50     return 0;
    51 }
    Codevs求逆序对

    于是就可以去做http://www.lydsy.com/JudgeOnline/problem.php?id=2141了哈哈哈

    终于码完了23333

    由于代码能力还不够最后还是对着调的。。。

    题解:http://blog.csdn.net/PoPoQQQ/article/details/40373903

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 long long read() {
     4     long long x = 0, f = 1; char ch = getchar();
     5     while (!isdigit(ch)) {
     6         if  (ch == '-') f = -1; ch = getchar();
     7     }
     8     while (isdigit(ch)) {
     9         x = x * 10 + ch - '0'; ch = getchar();
    10     }
    11     return x * f;
    12 }
    13 
    14 /*------------------------------template------------------------------*/
    15  
    16 #define M 20200  
    17 #define nxt(x) (x & -x)
    18 using namespace std;
    19 
    20 int n, m, ans, tot, block;
    21 int a[M];  
    22 pair<int, int> b[M];
    23 int pre[M], cnt[200][M];
    24 
    25 void up(int c[], int x) {  
    26     for(; x <= n; x += nxt(x)) ++c[x];  
    27 }
    28 
    29 void down(int c[], int x) {  
    30     for(; x <= n; x += nxt(x)) --c[x];  
    31 }
    32 
    33 int calc(int c[], int x) {  
    34     int re = 0;  
    35     for(; x; x -= nxt(x)) re+=c[x]; 
    36     return re;
    37 }
    38 
    39 int main() {  
    40     int x, y;  
    41     n = read();  
    42     for(int i = 1; i <= n; i ++) b[i] = make_pair(read(), i);  
    43     sort(b + 1, b + n + 1);
    44     for(int i = 1; i <= n; i ++) {  
    45         if (b[i].first != b[i - 1].first) ++tot;
    46         a[b[i].second] = tot;
    47     }
    48     for(int i = n; i; i --) ans += calc(pre, a[i] - 1), up(pre, a[i]);  
    49     printf("%d
    ", ans);
    50     //Get the first ans  
    51     block = static_cast<int>(sqrt(n) + 1e-7);
    52     for(int i = 1; i <= n; i ++) up(cnt[(i-1) / block], a[i]);
    53     //Blocking init
    54     m = read();
    55     for(int i = 1; i <= m; i ++) {  
    56         x = read(); y = read();
    57         if (x > y) swap(x, y);
    58         //查询(x, y)区间内有多少个数比a[x]和a[y]小  
    59         int b1 = (x - 1) / block + 1;  
    60         int b2 = (y - 1) / block - 1;  
    61         if (b1 <= b2) {  
    62             for(int j = b1; j <= b2; j ++) {  
    63                 ans -= calc(cnt[j], a[x] - 1);  
    64                 ans += calc(cnt[j], n) - calc(cnt[j], a[x]);  
    65                 ans += calc(cnt[j], a[y] - 1);  
    66                 ans -= calc(cnt[j], n) - calc(cnt[j], a[y]);  
    67             }  
    68             for(int j = x + 1; j <= b1 * block; j ++) {  
    69                 if (a[j] < a[x]) --ans;  
    70                 if (a[j] > a[x]) ++ans;  
    71                 if (a[j] < a[y]) ++ans;  
    72                 if (a[j] > a[y]) --ans;  
    73             }  
    74             for(int j = (b2 + 1) * block + 1; j < y; j ++) {  
    75                 if (a[j]<a[x]) --ans;  
    76                 if (a[j]>a[x]) ++ans;  
    77                 if (a[j]<a[y]) ++ans;  
    78                 if (a[j]>a[y]) --ans;  
    79             }  
    80         }  
    81         else {
    82             //暴力
    83             for(int j = x + 1; j <= y - 1; j ++) {  
    84                 if (a[j] < a[x]) --ans;  
    85                 if (a[j] > a[x]) ++ans;  
    86                 if (a[j] < a[y]) ++ans;  
    87                 if (a[j] > a[y]) --ans;  
    88             }  
    89         }  
    90         if (a[x] < a[y]) ++ans;  
    91         else if (a[x] > a[y]) --ans;  
    92         printf("%d
    ", ans);  
    93         down(cnt[(x-1) / block], a[x]);  
    94         down(cnt[(y-1) / block], a[y]);  
    95         swap(a[x], a[y]);
    96         up(cnt[(x-1) / block], a[x]);  
    97         up(cnt[(y-1) / block], a[y]);  
    98     }  
    99 }  
    BZOJ2141
  • 相关阅读:
    正则表达式的妙用获得数组
    道不远人,话IO框架
    页面和控件的生命周期及其二者的关系
    深度解析 TypeConverter & TypeConverterAttribute (二)
    今天我顺利的在cnblogs安家,我要在这里写下辉煌
    AJAX or Ajax
    深度解析 TypeConverter & TypeConverterAttribute (一)
    SonarQube简单入门
    vuecli · Failed to download repo vuejstemplates/webpack: connect ETIMEDOUT 192.30.253.112:443
    Sqlmap使用教程
  • 原文地址:https://www.cnblogs.com/xc01/p/6881487.html
Copyright © 2011-2022 走看看