zoukankan      html  css  js  c++  java
  • CodeForces 785E Anton and Permutation

    Anton and Permutation

    题意:给定一个 1-n的排列, 现在有m次操作, 每次操作交换 a[l],a[r] 求交换完之后整个序列的逆序对数是多少。

    题解:

    树状数组套主席树去维护。 感觉是一个主席树 + 树状数组套动态开点的线段树啊。 好久没写主席树了 都不会写了。。。

    每次交换 a[l] 和 a[r] 以后 有影响的只有区间[l, r]里面的数。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 //#define lson l,m,rt<<1
     10 //#define rson m+1,r,rt<<1|1
     11 #define max3(a,b,c) max(a,max(b,c))
     12 #define min3(a,b,c) min(a,min(b,c))
     13 typedef pair<int,int> pll;
     14 const int INF = 0x3f3f3f3f;
     15 const LL mod =  (int)1e9+7;
     16 const int N = 2e5 + 100;
     17 const int M = N * 100;
     18 int rt[N], S[N], lson[M], rson[M], cnt[M];
     19 int tot;
     20 int a[N];
     21 void PushUp(int x){
     22     cnt[x] = cnt[lson[x]] + cnt[rson[x]];
     23 }
     24 int Build(int l, int r){
     25     int x = ++tot;
     26     cnt[x] = 0;
     27     if(l < r){
     28         int m = l+r >> 1;
     29         lson[x] = Build(l, m);
     30         rson[x] = Build(m+1, r);
     31         PushUp(x);
     32     }
     33     return x;
     34 }
     35 int Update(int l, int r, int pre, int pos, int v){
     36 
     37     int x = ++tot;
     38     cnt[x] = cnt[pre] + v;
     39     if(l < r){
     40         int m = l+r >> 1;
     41         if(pos <= m){
     42             rson[x] = rson[pre];
     43             lson[x] = Update(l, m, lson[pre], pos, v);
     44         }
     45         else {
     46             lson[x] = lson[pre];
     47             rson[x] = Update(m+1, r, rson[pre], pos, v);
     48         }
     49         PushUp(x);
     50     }
     51     return x;
     52 }
     53 int Query(int l, int r, int L, int rt){
     54     if(!rt) return 0;
     55     if(l == r) return cnt[rt];
     56     int m = l + r >> 1;
     57     if(L <= m) return Query(l, m, L,lson[rt]);
     58     return cnt[lson[rt]] + Query(m+1, r, L, rson[rt]);
     59 }
     60 void Insert(int l,int r,int &i,int x,int val)
     61 {
     62     if( i==0) i = ++tot;
     63     cnt[i] += val;
     64     if(l == r) return ;
     65     int m = l+r >>1;
     66     if(x <= m) Insert(l, m, lson[i], x, val);
     67     else Insert(m+1, r, rson[i], x, val);
     68 }
     69 int lowbit(int x){
     70     return x&(-x);
     71 }
     72 int main(){
     73     tot = 0;
     74     int n, m;
     75     scanf("%d%d", &n, &m);
     76     int tmp = 0;
     77     rt[0] = Build(1, n);
     78     for(int i = 0; i <= n; i++) a[i] = i;
     79     for(int i = 1; i <= n; i++) rt[i] = Update(1, n, rt[i-1], i, 1);
     80     LL ans = 0;
     81     int l, r;
     82     while(m--){
     83         scanf("%d%d", &l, &r);
     84         if(l == r) {
     85             printf("%I64d
    ", ans);
     86             continue;
     87         }
     88         if(l > r) swap(l, r);
     89         if(l + 1 < r){
     90             int len = r - l - 1;
     91             int t1 = Query(1, n, a[r], rt[r-1]) - Query(1, n, a[r], rt[l]);
     92             for(int i = l; i ;i -= lowbit(i)) t1 -= Query(1, n, a[r], S[i]);
     93             for(int i = r-1; i;i -= lowbit(i)) t1 += Query(1, n, a[r], S[i]);
     94             int t2 = len - t1;
     95             ans += t1;
     96             ans -= t2;
     97             t1 = Query(1, n, a[l],rt[r-1]) - Query(1, n, a[l], rt[l]);
     98             for(int i = l; i > 0;i -= lowbit(i)) t1 -= Query(1, n, a[l], S[i]);
     99             for(int i = r-1; i > 0;i -= lowbit(i)) t1 += Query(1, n, a[l], S[i]);
    100             t2= len-t1;
    101             ans -= t1;
    102             ans += t2;
    103 
    104         }
    105         if(a[l] < a[r]) ans++;
    106         else ans--;
    107         printf("%I64d
    ", ans);
    108         for(int j = l; j <= n; j += lowbit(j)){
    109             Insert(1, n, S[j], a[l],-1);
    110             Insert(1, n, S[j], a[r], 1);
    111         }
    112         for(int j = r; j <= n; j += lowbit(j)){
    113             Insert(1, n, S[j], a[l], 1);
    114             Insert(1, n, S[j], a[r], -1);
    115         }
    116         swap(a[l], a[r]);
    117     }
    118     return 0;
    119 }
    View Code
  • 相关阅读:
    Shell中判断语句if中-z至-d的意思
    每日英语-20171129
    THINK PHP 学习笔记20171115
    每日英语-20171115
    git bash安装和基本设置
    Centos6.8搭建Git服务(git版本可选)
    一键安装lamp环境出现的问题
    用PHP实现反向代理服务器
    动词的过去式、过去分词、现在分词
    树莓派 中文
  • 原文地址:https://www.cnblogs.com/MingSD/p/9496255.html
Copyright © 2011-2022 走看看