zoukankan      html  css  js  c++  java
  • CF 540E, 树状数组

    题目大意:在1~10^9的范围内随便交换某些位置上的数,求逆序对数量,交换位置<=10^5

    解:因为是交换位置很少,离散化来做,逆序对可以看成两部分,一部分是出现位置的逆序对,另一部分的出现了的数对于没有交换位置上的数(没有在离散化中出现的数)的逆序对。分别统计一下,第一part用树状数组,第二part之间算一下区间实际的数字和有多少个交换了位置的数字即可。

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <utility>
     5 #include <map>
     6 #include <string>
     7 #include <cmath>
     8 #include <vector>
     9 #include <cstring>
    10 
    11 using namespace std;
    12 
    13 #define SQR(x) ((x)*(x))
    14 #define LL long long
    15 #define LOWBIT(x) ((x)&(-(x)))
    16 #define PB push_back
    17 #define MP make_pair
    18 
    19 #define MAXN 211111
    20 
    21 struct TreeArray{
    22     int tree[MAXN], n;
    23     void clear(int nn = MAXN - 10) {
    24         n = nn;
    25         memset(tree, 0, sizeof(tree[0]) * (n + 10));
    26     }
    27     void add(int x, int num = 1) {
    28         while (x <= n) {
    29             tree[x] += num;
    30             x += LOWBIT(x);
    31         }
    32     }
    33     int get(int x) {
    34         int res = 0;
    35         while (x > 0) {
    36             res += tree[x];
    37             x -= LOWBIT(x);
    38         }
    39         return res;
    40     }
    41 } TA;
    42 
    43 pair<int, int > query[MAXN];
    44 vector <int > lsh;
    45 vector <int > a;
    46 int n;
    47 LL ans;
    48 
    49 void init() {
    50     cin >> n;
    51     int x, y;
    52     lsh.clear();
    53     for (int i = 0; i < n; ++i) {
    54         cin >> x >> y;
    55         query[i] = MP(x, y);
    56         lsh.PB(x); lsh.PB(y);
    57     }
    58     sort(lsh.begin(), lsh.end()); 
    59     lsh.erase(unique(lsh.begin(), lsh.end()), lsh.end());
    60 }
    61 
    62 #define INDEX(x) ((lower_bound(lsh.begin(), lsh.end(), (x))-lsh.begin())+1)
    63 
    64 void solve() {
    65     ans = 0;
    66     a = lsh;
    67     TA.clear(lsh.size()+10);
    68     for (int i = 0; i < n; ++i) {
    69 //        cout << query[i].first <<' '<< query[i].second << endl;
    70         swap(a[INDEX(query[i].first)-1], a[INDEX(query[i].second)-1]);
    71     }
    72 
    73 //    for (int i = 0; i < lsh.size(); ++i) cout << lsh[i] <<' '; cout << endl;
    74 //    for (int i = 0; i < a.size(); ++i) cout << a[i] <<' '; cout << endl;
    75 
    76     for (int i = (int)a.size() - 1; i >= 0; --i) {
    77         ans += TA.get(INDEX(a[i]) - 1);
    78         TA.add(INDEX(a[i]));
    79         int key = 0, t;
    80         t = INDEX(a[i]) - 1;
    81         if (i < t) {
    82             key = (lsh[t] - lsh[i] - 1) - (t - i - 1);
    83         } 
    84         else {
    85             key = (lsh[i] - lsh[t] - 1) - (i - t - 1);
    86         }
    87         ans += key;
    88 //        cout << ans << endl;
    89     }
    90 }
    91 
    92 int main() {
    93 //    freopen("test.txt", "r", stdin);
    94     ios::sync_with_stdio(false);
    95     init();
    96     solve();
    97     cout << ans << endl;
    98     return 0;
    99 }
    CF 540E
  • 相关阅读:
    python 可变数据类型&不可变数据类型
    java异常 总结
    java 进制转换
    在virtualbox下使用vm映像文件
    关于C语言中单双引号的问题
    php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
    fastadmin model关联模型 关联查询问题
    php 解决跨域问题
    微信支付相关
    TP5之事务处理
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/5875042.html
Copyright © 2011-2022 走看看