• bzoj 3295 动态逆序对 CDQ分支


           容易看出ans[i]=ans[i-1]-q[i],q[i]为删去第i个数减少的逆序对。

           先用树状数组算出最开始的逆序对,预处理出每个数前边比它大的和后边比它小的,就求出了q[i]的初始值。

           设b[i]是第i个删除的数,pos[i]为i在数列里的位置。

           对q[i]产生影响的是   1. j<i,pos[b[j]]<pos[b[i]],b[j]>b[i].  2.j<i,pos[b[j]]>pos[b[i]],b[j]<b[i].

           因为是三维的,所以我们套一层cdq。

           

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define int long long
     6 #define N 100005
     7 using namespace std;
     8 int n,m;
     9 int a[N],b[N],d[N];
    10 int c[N];
    11 int ans[N];int p[N];
    12 int qur(int x)
    13 {
    14     int tp=0;
    15     for(int i=x;i;i-=(i&-i))tp+=c[i];
    16     return tp;
    17 }
    18 void add(int x,int z)
    19 {
    20     for(int i=x;i<=n;i+=(i&-i))c[i]+=z;
    21     return ;
    22 }
    23 int tmp[N];int q[N];
    24 bool cmp(int x,int y)
    25 {
    26     return p[x]<p[y];
    27 }
    28 void solve(int l,int r)
    29 {
    30     if(l==r)return ;
    31     int mid=(l+r)>>1;
    32     int cnt=0;
    33     for(int i=l;i<=r;i++)tmp[++cnt]=b[i];
    34     sort(tmp+1,tmp+cnt+1,cmp);
    35     for(int i=1;i<=cnt;i++)
    36     {
    37         if(d[tmp[i]]<=mid)add(tmp[i],1);
    38         else q[tmp[i]]-=qur(n)-qur(tmp[i]);
    39     }
    40     for(int i=1;i<=cnt;i++)if(d[tmp[i]]<=mid)add(tmp[i],-1);
    41     for(int i=cnt;i>=1;i--)
    42     {
    43         if(d[tmp[i]]<=mid)add(tmp[i],1);
    44         else q[tmp[i]]-=qur(tmp[i]);
    45     }
    46     for(int i=1;i<=cnt;i++)if(d[tmp[i]]<=mid)add(tmp[i],-1);
    47     solve(l,mid);solve(mid+1,r);
    48     return ;
    49 }
    50 signed main()
    51 {
    52     scanf("%lld%lld",&n,&m);
    53     for(int i=1;i<=n;i++)scanf("%lld",&a[i]),p[a[i]]=i;
    54     for(int i=1;i<=m;i++)scanf("%lld",&b[i]),d[b[i]]=i;
    55     for(int i=1;i<=n;i++)
    56     {
    57         int tp=qur(n)-qur(a[i]);
    58         ans[0]+=tp;
    59         q[a[i]]+=tp;
    60         add(a[i],1);
    61     }
    62     memset(c,0,sizeof(c));
    63     for(int i=n;i>=1;i--)
    64     {
    65         int tp=qur(a[i]);
    66         q[a[i]]+=tp;
    67         add(a[i],1);
    68     }
    69     memset(c,0,sizeof(c));
    70     solve(1,m);
    71     for(int i=1;i<m;i++)ans[i]=ans[i-1]-q[b[i]];
    72     for(int i=0;i<m;i++)printf("%lld
    ",ans[i]);
    73     return 0;
    74 }
  • 相关阅读:
    JAVA 8的新特性
    JAVA中map的分类和各自的特性
    设计模式之工厂方法模式(附实例代码下载)
    为什么重写equals还要重写hashcode??
    C# static的用法详解
    1-RadioButton控件的用法
    C#三种常用的读取XML文件的方法
    VS2017 中安装SVN
    pip安装selenium时,报错“You are using pip version 10.0.1, however version 18.0 is available.”的问题
    问题:unknown error: call function result missing 'value' 解决方法
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6165830.html
Copyright © 2020-2023  润新知