• luogu P3157 [CQOI2011]动态逆序对(CDQ分治)


    题目描述

    对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。

    输入输出格式

    输入格式:

    输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数。以下n行每行包含一个1到n之间的正整数,即初始排列。以下m行每行一个正整数,依次为每次删除的元素。

    输出格式:

    输出包含m行,依次为删除每个元素之前,逆序对的个数。

    题解

    我们发现一个数的贡献,就是就是t'<t(删除时间),xb'<xb(下标),w'>w(权值)的数的数量和t'>t,xb'>xb,w'<w的数的数量之和。

    这就是一个三维偏序类型的题,所以做两遍CDQ分治分别的到这两种贡献。最后用总逆序对数减去就好了。

    1A真开心。。。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstdio>
      5 #include<cmath>
      6 using namespace std;
      7 const long long N=100100;
      8 long long n,m,a[N],b[N],tmp,tr[N],ans[N],book[N],ma[N],tot;
      9 struct query{
     10     long long id,xb,w;
     11 }q[N],c[N];
     12 bool cmp(query a,query b){
     13     return a.id>b.id;
     14 }
     15 void gb(long long l,long long r){
     16     if(l==r)return;
     17     long long mid=(l+r)>>1;
     18     gb(l,mid);
     19     gb(mid+1,r);
     20     long long ll=l;
     21     long long lr=mid+1;
     22     long long cnt=0;
     23     while(ll<=mid&&lr<=r){
     24         cnt++;
     25         if(a[ll]<a[lr]){
     26             b[cnt]=a[ll++];
     27         }
     28         else{
     29             b[cnt]=a[lr++];
     30             tmp+=mid-ll+1;
     31         }
     32     }
     33     while(ll<=mid)b[++cnt]=a[ll++];
     34     while(lr<=r)b[++cnt]=a[lr++];
     35     for(long long i=l;i<=r;i++){
     36         a[i]=b[i-l+1];
     37     }
     38 }
     39 long long lowbit(long long x){
     40     return x&-x;
     41 }
     42 void add(long long x,long long w){
     43     for(long long i=x;i<=n;i+=lowbit(i)){
     44         tr[i]+=w;
     45     }
     46 }
     47 long long getsum(long long x){
     48     long long ans=0;
     49     for(long long i=x;i>=1;i-=lowbit(i)){
     50         ans+=tr[i];
     51     }
     52     return ans;
     53 }
     54 void cdq(long long l,long long r){
     55     if(l==r)return;
     56     long long mid=(l+r)>>1;
     57     cdq(l,mid);cdq(mid+1,r);
     58     long long ll=l;long long rl=mid+1;long long now=0;
     59     while(ll<=mid&&rl<=r){
     60         if(q[ll].xb<q[rl].xb){
     61             add(q[ll].w,1);
     62             c[++now]=q[ll++];
     63         }
     64         else{
     65             ans[q[rl].id]+=getsum(n)-getsum(q[rl].w);
     66             c[++now]=q[rl++];
     67         }
     68     }
     69     while(ll<=mid){
     70         add(q[ll].w,1);
     71         c[++now]=q[ll++];
     72     }
     73     while(rl<=r){
     74         ans[q[rl].id]+=getsum(n)-getsum(q[rl].w);
     75         c[++now]=q[rl++];
     76     }
     77     for(long long i=l;i<=mid;i++)add(q[i].w,-1);    
     78     for(long long i=l;i<=r;i++)q[i]=c[i-l+1];
     79 }
     80 void CDQ(long long l,long long r){
     81     if(l==r)return;
     82     long long mid=(l+r)>>1;
     83     CDQ(l,mid);CDQ(mid+1,r);
     84     long long ll=l;long long rl=mid+1;long long now=0;
     85     while(ll<=mid&&rl<=r){
     86         if(q[ll].xb>q[rl].xb){
     87             add(q[ll].w,1);
     88             c[++now]=q[ll++];
     89         }
     90         else{
     91             ans[q[rl].id]+=getsum(q[rl].w);
     92             c[++now]=q[rl++];
     93         }
     94     }
     95     while(ll<=mid){
     96         add(q[ll].w,1);
     97         c[++now]=q[ll++];
     98     }
     99     while(rl<=r){
    100         ans[q[rl].id]+=getsum(q[rl].w);
    101         c[++now]=q[rl++];
    102     }
    103     for(long long i=l;i<=mid;i++)add(q[i].w,-1);
    104     for(long long i=l;i<=r;i++)q[i]=c[i-l+1];
    105 }
    106 int main(){
    107     scanf("%lld%lld",&n,&m);
    108     for(long long i=1;i<=n;i++){
    109         scanf("%lld",&a[i]);
    110         ma[a[i]]=i;
    111     }
    112     for(long long i=1;i<=m;i++){
    113         long long x;
    114         scanf("%lld",&x);
    115         q[i].id=i;q[i].xb=ma[x];q[i].w=x;
    116         book[ma[x]]=1;
    117     }
    118     tot=m;
    119     for(long long i=1;i<=n;i++){
    120         if(book[i]==0){
    121             q[++tot].id=m+1;q[tot].xb=i;q[tot].w=a[i];
    122         }
    123     }
    124     sort(q+1,q+n+1,cmp);
    125     cdq(1,n);
    126     sort(q+1,q+n+1,cmp);
    127     CDQ(1,n);
    128     gb(1,n);
    129     for(long long i=1;i<=m;i++){
    130         printf("%lld
    ",tmp);
    131         tmp-=ans[i];
    132     }
    133     return 0;
    134 }
  • 相关阅读:
    SpringBoot集成beetl模板快速入门
    小记---idea springboot 报错没有get或者set方法
    android在style中使用自定义属性 error: style attribute not found.
    ieda使用 在jsp页面中,有时候会出现不能智能显示方法 idea pageContext.setAttribute
    ieda使用 在jsp页面中,有时候会出现不能智能显示方法 idea pageContext.setAttribute
    logback的使用和logback.xml详解,在Spring项目中使用log打印日志
    classpath和classpath*区别
    SpringBoot项目在IntelliJ IDEA中实现热部署
    idea 警告:Warning:java: 源值1.5已过时, 将在未来所有发行版中删除
    linux 删除文件后 df 查看磁盘空间并没有释放
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9460134.html
Copyright © 2020-2023  润新知