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
  • 相关阅读:
    centos 安装 redis3.2.0 集群
    CentOS7安装配置redis-3.0.0
    CentOS7/RHEL7安装Redis步骤详解
    鸟哥之安裝 CentOS7.x
    Centos 7 学习之静态IP设置
    CentOS7 下linux不能上网解决方法​,centos7 eth0 没有ip,IP突然丢失
    javamail发送邮件(转)
    Apache James使用的方法及相关心得(转)
    Velocity缓存与穿透(转)
    十分钟搞懂什么是CGI(转)
  • 原文地址:https://www.cnblogs.com/MengX/p/11503124.html
Copyright © 2011-2022 走看看