zoukankan      html  css  js  c++  java
  • 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]);
    }
  • 相关阅读:
    Django笔记&教程 2-2 URL详细匹配规则
    Django笔记&教程 2-3 视图(view)函数介绍
    前端基础之HTML
    Python基础之(并发编程)
    Git常用命令
    Python基础之(Socket编程)
    Python基础之(异常与开发规范)
    Python基础之(面向对象进阶)
    Python基础之(面向对象初识)
    Python基础之(常用模块)
  • 原文地址:https://www.cnblogs.com/kls123/p/9530823.html
Copyright © 2011-2022 走看看