#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 200001
using namespace std; typedef long long ll;
ll ans[maxn],Ans;
int n,m,tot,tsum[maxn],num[maxn],pos[maxn],sum[maxn],_num[maxn];
bool bo[maxn]; struct date{
int bo,id,x,y;
}qs[maxn],temp[maxn]; int lowbit(int x){
return x&(-x);
} void insert(int x,int y){
for (int i=x;i<=n;i+=lowbit(i)) sum[i]+=y;
} int qsum(int x){
int tmp=; for (int i=x;i;i-=lowbit(i)) tmp+=sum[i];
return tmp;
} void tinsert(int x){
for (int i=x;i<=n;i+=lowbit(i)) tsum[i]++;
} int tqsum(int x){
int tmp=;
for (int i=x;i>;i-=lowbit(i)){
tmp+=tsum[i];
}
return tmp;
} bool comp(date x,date y){
return x.x<y.x;
} bool comp2(date x,date y){
return x.id<y.id;
} void cdq_solve(int l,int r){
if (l==r) return;
int mid=(l+r)/,tmp=; cdq_solve(l,mid),cdq_solve(mid+,r);
sort(qs+l,qs+mid+,comp),sort(qs+mid+,qs+r+,comp);
for (int i=l,j=mid+;j<=r;){
for (;i<=mid&&qs[i].bo==;i++);
for (;j<=r&&qs[j].bo==;j++);
if (j>r) break;
if (qs[i].x<qs[j].x&&i<=mid) insert(qs[i].y,),tmp=i++;
else ans[qs[j].id]+=qsum(qs[j].y-),j++;
}
for (int i=l;i<=tmp;i++) if (qs[i].bo==) insert(qs[i].y,-);
} int main(){
// freopen("dtnxd.in","r",stdin);
// freopen("dtnxd.out","w",stdout);
int u,v;
memset(sum,,sizeof(sum));
memset(tsum,,sizeof(tsum)),Ans=;
memset(bo,,sizeof(bo));
memset(ans,,sizeof(ans));
scanf("%d%d",&n,&m),tot=;
for (int i=;i<=n;i++) scanf("%d",&u),pos[u]=i,_num[i]=u;
for (int i=m;i>=;i--) scanf("%d",&num[i]),bo[pos[num[i]]]=;
for (int i=n;i>=;i--){
if (bo[i]==){
Ans+=tqsum(_num[i]-);
tinsert(_num[i]);
}
}
for (int i=;i<=n;i++){
if (!bo[i]) u=_num[i],++tot,qs[tot].bo=,qs[tot].x=u,qs[tot].y=i,qs[tot].id=tot;
}
for (int i=;i<=m;i++){
u=num[i],v=pos[u];
qs[++tot].bo=,qs[tot].x=u,qs[tot].y=v,qs[tot].id=tot;
qs[++tot].bo=,qs[tot].x=u,qs[tot].y=v,qs[tot].id=tot;
}
// for (int i=1;i<=tot;i++) printf("%d %d %d %d\n",qs[i].x,qs[i].y,qs[i].bo,qs[i].id);
for (int i=;i<=tot;i++){
temp[i]=qs[i];
qs[i].x=n+-qs[i].x;
}
cdq_solve(,tot);
for (int i=;i<=tot;i++){
qs[i]=temp[i];
qs[i].y=n+-qs[i].y;
}
cdq_solve(,tot);
sort(qs+,qs+tot+,comp2);
// for (int i=1;i<=tot;i++) printf("%d %lld\n",i,ans[i]);
for (int i=;i<=tot;i++) ans[i]+=ans[i-];
for (int i=tot;i>;i--) if (qs[i].bo==) printf("%lld\n",ans[i]+Ans);
return ;
}

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3295

题目大意:见上一篇博客。

做法:上一篇博客中,我介绍了树套树的做法,现在我来讲讲cdq分治的做法。

求逆序对的常用做法除了用树状数组维护以外,还可以用归并排序求,其本质是cdq分治。

cdq分治做法:

题目中是删除一些数,我们可以离线,看作是往序列中不断地加入一些数每加入一个数字,我们考虑它对答案带来的影响,它对答案的影响就是ans+=目前的序列中排在它前面的比它大的数的个数+排在它后面的比它小的数的个数。简化之后就是给定若干个三元组(x,y,z),x就是题目中操作的顺序(稍微调整一下即可),y表示这个数的权值,z表示这个数的位置,这些三元组中有些是询问,有些是修改,对于询问,就是求修改中x比它的X小的、y比它的Y大的、z比它的小的个数+修改中x比它的X小的、y比它的小的、z比它的大的个数,对于这种三维偏序问题,我们考虑cdq分治,第一维分治外层,第二维排序,第三位树状数组维护即可。

cdq分治+树状数组

bzoj3295: [Cqoi2011]动态逆序对(cdq分治)的更多相关文章

  1. [BZOJ3295][Cqoi2011]动态逆序对 CDQ分治&树套树

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j,且 ...

  2. bzoj3295: [Cqoi2011]动态逆序对(cdq分治+树状数组)

    3295: [Cqoi2011]动态逆序对 题目:传送门 题解: 刚学完cdq分治,想起来之前有一道是树套树的题目可以用cdq分治来做...尝试一波 还是太弱了...想到了要做两次cdq...然后伏地 ...

  3. BZOJ3295 [Cqoi2011]动态逆序对 —— CDQ分治

    题目链接:https://vjudge.net/problem/HYSBZ-3295 3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 1 ...

  4. BZOJ3295:[CQOI2011]动态逆序对(CDQ分治)

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

  5. 【BZOJ3295】[Cqoi2011]动态逆序对 cdq分治

    [BZOJ3295][Cqoi2011]动态逆序对 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依 ...

  6. bzoj3295 [Cqoi2011]动态逆序对 cdq+树状数组

    [bzoj3295][Cqoi2011]动态逆序对 2014年6月17日4,7954 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数. ...

  7. [CQOI2011]动态逆序对 CDQ分治

    洛谷上有2道相同的题目(基本是完全相同的,输入输出格式略有不同) ---题面--- ---题面--- CDQ分治 首先由于删除是很不好处理的,所以我们把删除改为插入,然后输出的时候倒着输出即可 首先这 ...

  8. 洛谷 P3157 [CQOI2011]动态逆序对 | CDQ分治

    题目:https://www.luogu.org/problemnew/show/3157 题解: 1.对于静态的逆序对可以用树状数组做 2.我们为了方便可以把删除当成增加,可以化动为静 3.找到三维 ...

  9. BZOJ 3295: [Cqoi2011]动态逆序对 [CDQ分治]

    RT 传送门 首先可以看成倒着插入,求逆序对数 每个数分配时间(注意每个数都要一个时间)$t$,$x$位置,$y$数值 $CDQ(l,r)$时归并排序$x$ 然后用$[l,mid]$的加入更新$[mi ...

  10. P3157 [CQOI2011]动态逆序对 CDQ分治

    一道CDQ分治模板题简单来说,这道题是三维数点对于离线的二维数点,我们再熟悉不过:利用坐标的单调递增性,先按更坐标排序,再按纵坐标排序更新和查询时都直接调用纵坐标.实际上,我们是通过排序将二维中的一维 ...

随机推荐

  1. c语言 指针与地址的区别

    指针由两部分组成,指针的类型和指针的值(也就是变量的地址). 指针和地址的区别: 地址只是一堆十六进制的字符,对应着内存条的某段内存, 而指针本身有地址,指针的值也是一个地址,指针本身还有类型,这与单 ...

  2. Spire.Doc组件读取与写入Word

    之前写了一篇开源组件DocX读写word的文章,当时时间比较匆忙选了这个组件,使用过程中还是有些不便,不能提前定义好模版,插入Form表单域进行替换.最近无意中发现Spire.Doc组件功能很强大,目 ...

  3. PRML读书会第十一章 Sampling Methods(MCMC, Markov Chain Monte Carlo,细致平稳条件,Metropolis-Hastings,Gibbs Sampling,Slice Sampling,Hamiltonian MCMC)

    主讲人 网络上的尼采 (新浪微博: @Nietzsche_复杂网络机器学习) 网络上的尼采(813394698) 9:05:00  今天的主要内容:Markov Chain Monte Carlo,M ...

  4. 实用工具 : Xaml Power Toys

    最近挺忙, 憋了一肚子的东西没有分享. 今天分享一个 Xamarin.Forms / WPF 的增强工具 , Visual Studio 扩展 : Xaml Power Toy 可以直接在 VS201 ...

  5. swagger editor使用

    swagger editor使用 swagger是一套开源的API设计工具,包括Swagger UI,Swagger Editor等. Swagger Editor 其中Swagger Editor是 ...

  6. How to build windows azure PowerShell Source Code

    Download any version source code of Windows Azure Powershell from https://github.com/Azure/azure-sdk ...

  7. Android开发环境部署

    引言   在windows系统中安装Android的开发环境,将分为五个步骤来完成: 第一步:安装JDK 第二步:配置Windows上JDK的变量环境 第三步: 下载安装Eclipse 第四步:下载安 ...

  8. java中的URLConnection

    *URLConnection是个抽象类,它有两个直接子类分别是HttpURLConnection和JarURLConnection.另外一个重要的类是URL,通常URL可以通过传给构造器一个Strin ...

  9. 自然数从1到n之间,有多少个数字含有1

        问题明确而简单.for循环肯定是不好的.       用递推方法:       定义h(n)=从1到9999.....9999  ( n 个 9)之间含有1的数字的个数.定义f(n)为n位数中 ...

  10. Vim块注释

    如何在VIM下快速注释块代码 添加块注释 01.进入视图模式 v进入视图模式,控制方向键选中注释的代码 02.进入列模式并插入# ctrl+v进入列,I插入注释# 03.全部注释 esc两次自动全部注 ...