• bzoj 2141 : 排队 (cdq分治+bit)


    链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2141

    思路:

    其实就是求动态逆序对。。。cdq降维,用树状数组前后求两遍逆序对就好了

    切水题真爽QAQ

    实现代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int M = 1e5+10;
    int c[M<<2],a[M],b[M],ans[M];
    int n,m;
    struct node{
        int x,y,t;
        int kind,id;
        node(){}
        node(int a,int b,int c,int d,int e):t(a),x(b),y(c),kind(d),id(e){}
        bool operator < (const node &k) const {
            if(x == k.x) return t < k.t;
            return x < k.x;
        }
    }q[M],t[M];
    
    void add(int x,int val){
        while(x <= n){
            c[x] += val;
            x += (x&-x);
        }
    }
    
    int getsum(int x){
        int sum = 0;
        while(x){
            sum += c[x];
            x -= (x&-x);
        }
        return sum;
    }
    
    void cdq(int l,int r){
        if(l >= r) return ;
        int mid = (l + r) >> 1;
        for(int i = l;i <= r;i ++){
            if(q[i].t <= mid) add(q[i].y,q[i].kind);
            else ans[q[i].id] += q[i].kind*(getsum(n) - getsum(q[i].y));
        }
        for(int i = l;i <= r;i ++)
            if(q[i].t <= mid) add(q[i].y,-q[i].kind);
    
        for(int i = r;i >= l;i --){
            if(q[i].t <= mid) add(q[i].y,q[i].kind);
            else ans[q[i].id] += q[i].kind*(getsum(q[i].y-1));
        }
        for(int i = r;i >= l;i --)
            if(q[i].t <= mid) add(q[i].y,-q[i].kind);
    
        int L = l,R = mid+1;
        for(int i = l;i <= r;i ++){
            if(q[i].t <= mid) t[L++] = q[i];
            else t[R++] = q[i];
        }
        for(int i = l;i <= r;i ++) q[i] = t[i];
        cdq(l,mid); cdq(mid+1,r);
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i = 1;i <= n;i ++){
            scanf("%d",&a[i]);
            b[i] = a[i];
        }
        int cnt = 0;
        sort(b+1,b+1+n);
        int len = unique(b+1,b+1+n)-b-1;
        for(int i = 1;i <= n;i ++){
            a[i] = lower_bound(b+1,b+len+1,a[i])-b;
            q[++cnt] = node(cnt,i,a[i],1,0);
        }
        scanf("%d",&m);
        for(int i = 1;i <= m;i ++){
            int x,y;
            scanf("%d%d",&x,&y);
            q[++cnt] = node(cnt,x,a[y],1,i);
            q[++cnt] = node(cnt,x,a[x],-1,i);
            q[++cnt] = node(cnt,y,a[x],1,i);
            q[++cnt] = node(cnt,y,a[y],-1,i);
            swap(a[x],a[y]);
        }
        sort(q+1,q+cnt+1);
        cdq(1,cnt);
        printf("%d
    ",ans[0]);
        for(int i = 1;i <= m;i ++){
            ans[i] += ans[i-1];
        }
        for(int i = 1;i <= m;i ++)
            printf("%d
    ",ans[i]);
    }
  • 相关阅读:
    258. Add Digits 数位相加到只剩一位数
    7. Reverse Integer 反转整数
    9. Palindrome Number 回文数的判断
    824. Goat Latin山羊拉丁文
    819. Most Common Word 统计高频词(暂未被禁止)
    Angular 2 模板语法
    HTML DOM Style opacity 属性
    Basic concepts (C language) – C 中文开发手册
    JavaScript手册 | JS Array 对象中的fill()方法
    HTML <form> 标签
  • 原文地址:https://www.cnblogs.com/kls123/p/9530823.html
Copyright © 2020-2023  润新知