zoukankan      html  css  js  c++  java
  • [BZOJ3295] [Cqoi2011]动态逆序对 (cdq分治)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3295

    思路:

    第一种:我们可以按照删除的顺序变换成插入顺序 最先删除的就是最后插入的  然后就求逆序对啦

    第二种:我们考虑删掉每个点对序列的贡献 

    设当前删除了第x个元素,那么在1−x中比它大的都要减去 (x+1)N中比他小的都要减去

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn = 200005;
    int n,m,cnt;
    int a[maxn],pos[maxn],tree[maxn];
    ll ans[maxn];
    struct node{
        int t,x,val,type,id;
        bool friend operator<(const node u,const node v){
            if(u.x==v.x) return u.val<v.val;
            return u.x<v.x;
        }
    }q[maxn],p[maxn];
    int lowbit(int x){
        return x&(-x);
    }
    void add(int x,int val){
        while(x<=n){
            tree[x]+=val;
            x+=lowbit(x);
        }
    }
    int get_sum(int x){
        int res=0;
        while(x){
            res+=tree[x];
            x-=lowbit(x);
        }
        return res;
    }
    void cdq(int l,int r){
        if(l==r) return ;
        int m=(l+r)>>1;
        for(int i=l;i<=r;i++){
            if(q[i].t<=m) add(q[i].val,q[i].type);
            else 
                ans[q[i].id]+=q[i].type*(get_sum(n)-get_sum(q[i].val));
        }
        for(int i=l;i<=r;i++){
            if(q[i].t<=m) add(q[i].val,-q[i].type);
        }
        for(int i=r;i>=l;i--){
            if(q[i].t<=m) add(q[i].val,q[i].type);
            else ans[q[i].id]+=q[i].type*get_sum(q[i].val-1);
        }
        for(int i=l;i<=r;i++){
            if(q[i].t<=m) add(q[i].val,-q[i].type);
        }
        int q1=l;
        int q2=m+1;
        for(int i=l;i<=r;i++){
            if(q[i].t<=m) p[q1++]=q[i];
            else p[q2++]=q[i];
        }
        for(int i=l;i<=r;i++)
            q[i]=p[i];
        cdq(l,m);
        cdq(m+1,r);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            pos[a[i]]=i;
            q[++cnt]=node({cnt,i,a[i],1,0});
        }
        for(int i=1;i<=m;i++){
            int x;
            scanf("%d",&x);
            q[++cnt]=node({cnt,pos[x],x,-1,i});
        }
        sort(q+1,q+1+cnt);
        cdq(1,cnt);
        for(int i=1;i<=m;i++){
            printf("%lld
    ",ans[i-1]);
            ans[i]+=ans[i-1];
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Leetcode192. 统计词频
    Leetcode1046. 最后一块石头的重量
    Ubuntu20.04 NS3安装配置
    Ubuntu20.04 中文输入法+截图设置+NetAnim安装
    如何注册谷歌邮箱Gmail
    HDU 2612 Find a way
    友链
    2020沈阳区域赛补题&总结
    XShell中设置便捷的复制粘贴
    Hyper Text 超文本
  • 原文地址:https://www.cnblogs.com/MengX/p/11503124.html
Copyright © 2011-2022 走看看