【Luogu1393】动态逆序对(CDQ分治)

题面

题目描述

对于给定的一段正整数序列,我们定义它的逆序对的个数为序列中ai>aj且i < j的有序对(i,j)的个数。你需要计算出一个序列的逆序对组数及其删去其中的某个数的逆序对组数。

输入输出格式

输入格式:

第一行,两个数n,m,表示序列中有n个数,要删去m个数

第二行n个数,表示给定的序列。

第三行m个数,第i个数di表示要删去原序列中的第di个数。

输出格式:

一行m+1个数。第一个数表示给定序列的逆序对组数,第i+1个数表示删去第di个数后序列的逆序对组数(删去的数不再恢复)

输入输出样例

输入样例#1:

6 3

5 4 2 6 3 1

2 1 4

输出样例#1:

11 7 4 2

说明

对于20%的数据,n≤2500

对于另30%的数据,m=0

对于100%的数据,n≤40000,m≤n/2,且保证第二行n个数互不相同,第三行m个数互不相同

题解

之前不是说过要写一遍CDQ分治吗??

在这里说的

可是,当你把上面的代码兴高采烈的Copy到洛谷上之后

你就会直接WA了

因为,题目还是有点不同的(仔细读题)

区别一:这题不是排列,要离散化

区别二:这题删掉的不是数字,而是位置

好了回归正题,讲讲CDQ分治怎么写

首先,给所有删掉的数编个号,就按照删去的顺序来吧

没有删掉的数就编个INF吧

那么,删掉这个数之后,减少的逆序对对数是:

对于\(j\in[1,j]\)

\(t[i]<t[j]\),其中t是删除的编号

并且

\(i<j,a[i]>a[j]\)

或者

\(i>j,a[i]<a[j]\)

所以,删除的编号直接sort搞完

剩下的两维CDQ分治

于是,发现这个玩意是一个三维偏序

所以之前写过的树状数组套平衡树当然也可以做啦

但是,CDQ分治还是要会嗷。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 50000
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n,m,S[MAX],a[MAX],b[MAX],c[MAX],d[MAX];
long long ans;
int lowbit(int x){return x&(-x);}
void Add(int x,int w){while(x<=n)c[x]+=w,x+=lowbit(x);}
int getsum(int x){int ret=0;while(x)ret+=c[x],x-=lowbit(x);return ret;}
struct Node
{
int t,p,a;
int s;
}t[MAX];
bool operator<(Node a,Node b){return a.t<b.t;}
bool cmp(Node a,Node b){return a.p<b.p;}
void CDQ(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
CDQ(l,mid);CDQ(mid+1,r);
sort(&t[l],&t[mid+1],cmp);
sort(&t[mid+1],&t[r+1],cmp);
int j=mid;
for(int i=l;i<=mid;++i)
{
while(j<r&&t[j+1].p<t[i].p)++j,Add(t[j].a,1);
t[i].s+=getsum(n)-getsum(t[i].a);
}
for(int i=mid+1;i<=j;++i)Add(t[i].a,-1);
j=r+1;
for(int i=mid;i>=l;--i)
{
while(j>mid+1&&t[j-1].p>t[i].p)--j,Add(t[j].a,1);
t[i].s+=getsum(t[i].a-1);
}
for(int i=r;i>=j;--i)Add(t[i].a,-1);
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;++i)S[i]=a[i]=read();
sort(&S[1],&S[n+1]);
for(int i=1;i<=n;++i)b[a[i]=lower_bound(&S[1],&S[n+1],a[i])-S]=i;
for(int i=n;i;i--)ans+=getsum(a[i]),Add(a[i],1);
for(int i=1;i<=n;++i)t[i].t=n+1,t[i].p=i,t[i].a=a[i];
for(int i=1;i<=m;++i)
{
d[i]=read();
t[d[i]].t=i;
}
sort(&t[1],&t[n+1]);
memset(c,0,sizeof(c));
CDQ(1,n);
for(int i=1;i<=n;++i)c[t[i].p]=t[i].s;
printf("%lld ",ans);
for(int i=1;i<=m;++i)
printf("%lld ",ans=ans-c[d[i]]);
return 0;
}

【Luogu1393】动态逆序对(CDQ分治)的更多相关文章

  1. P3157 动态逆序对 CDQ分治

    动态逆序对 CDQ分治 传送门:https://www.luogu.org/problemnew/show/P3157 题意: 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对 ...

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

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

  3. BZOJ 3295 动态逆序对 | CDQ分治

    BZOJ 3295 动态逆序对 这道题和三维偏序很类似.某个元素加入后产生的贡献 = time更小.pos更小.val更大的元素个数 + time更小.pos更大.val更小的元素个数. 分别用类似C ...

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

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

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

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

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

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

  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. BZOJ3295:[CQOI2011]动态逆序对(CDQ分治)

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

随机推荐

  1. Spring bean的生命周期详解

    bean的生命周期1.实例化bean 即new2.按照spring上下文对实例化的bean进行配置 即填充属性,也就是IOC/DI(控制反转,依赖注入)3.如果这个bean实现了BeanNameAwa ...

  2. openvpn服务器一键脚本生成客户端文件

    #!/bin/bash #获取参数 while getopts "n:" opt; do case $opt in n) client_name=$OPTARG ;; \?) ;; ...

  3. 洛谷P4014 分配问题【最小/大费用流】题解+AC代码

    洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...

  4. MYSQL EXPLAIN执行计划命令详解(支持更新中)

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 本篇是根据官网中的每个一点来翻译.举例.验证的:英语不好,所 ...

  5. maven排除jar包冲突

    首先查看mvn中冲突的包 使用命令:mvn dependency:tree -Dverbose | grep "omitted for conflict with" windows ...

  6. vue父子组件之间的通信

    利用props在子组件接受父组件传过来的值1.父组件parentComp.vue <template> <childComp :fromParentToChild="fro ...

  7. Mysql 远程登录及常用命令

    第一招.mysql服务的启动和停止 net stop mysql net start mysql 第二招.登陆mysql 语法如下: mysql -u用户名 -p用户密码 键入命令mysql -uro ...

  8. windows转mac-开发环境搭建(二):mac上java环境搭建

    1.首先下载jdk,地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2.安 ...

  9. react+react-router+react-redux+nodejs+mongodb项目

    一个实际项目(OA系统)中的部分功能.这个demo中引入了数据库,数据库使用了mongodb.安装mongodb才能运行完整的功能.要看完整的项目可以移步我的github 技术栈 React v15. ...

  10. JavaScript网页全屏API

    在大多数的浏览器中都有实现网页全屏显示的功能,并且大部分浏览器实现全屏显示和退出全屏显示的快捷键通常是F11和Esc两个按键.如今,W3C已经制定了关于网页全屏显示的API,利用这个API 可以实现网 ...