P3157 [CQOI2011]动态逆序对 CDQ分治
一道CDQ分治模板题
简单来说,这道题是三维数点
对于离线的二维数点,我们再熟悉不过:利用坐标的单调递增性,先按更坐标排序,再按纵坐标排序
更新和查询时都直接调用纵坐标。
实际上,我们是通过排序将二维中的一维给消掉了。
那么,对于题中的三维数点,我们可以先按 $x$ 排序,以 $x$ 为标准进行分治
在分治的过程中,分别对左右区间按 $y$ 来排序。
由于左面的 $x$ 坐标一定是小于右面的 $x$ 坐标的。
所以这一维可以被我们消掉。
剩下的就是一个二维数点问题了,只需按照顺序依次更新 $z$ 即可。
(反正左面的 $x$ 比右面小,而且 $y$ 也一定比右面小,只要 $z$ 比右面小是都能统计出来的)
Code:
#include <cstdio>
#include <algorithm>
#include <cstring>
#define setIO(s) freopen(s".in","r",stdin) ,freopen(s".out","w",stdout)
#define maxn 1000006
using namespace std;
int n,m,idx,place[maxn],C[maxn];
long long ans[maxn];
struct BIT{
int lowbit(int x) { return x&(-x); }
void add(int pos,int x){
while(pos<=n) C[pos]+=x,pos+=lowbit(pos);
}
int ask(int pos){
int sum=0;
while(pos>0) sum+=C[pos],pos-=lowbit(pos);
return sum;
}
}tree;
struct OPT{
int x,y,z,rnk,kind,id;
}opt[maxn],tmp[maxn];
bool cmp(OPT i,OPT j)
{
return (i.x==j.x&&i.y==j.y)?(i.rnk<j.rnk):((i.x==j.x)?i.y<j.y:i.x<j.x);
}
void solve(int L,int R)
{
if(L>=R) return;
int mid=(L+R)>>1,tl=L-1,tr=mid;
for(int i=L;i<=R;++i){
if(opt[i].rnk<=mid&&opt[i].kind==1) tree.add(opt[i].y,opt[i].z);
if(opt[i].rnk>mid&&opt[i].kind==2) ans[opt[i].id]+=tree.ask(opt[i].y)*opt[i].z;
}
for(int i=L;i<=R;++i)
if(opt[i].rnk<=mid&&opt[i].kind==1) tree.add(opt[i].y,-opt[i].z);
for(int i=L;i<=R;++i) {
if(opt[i].rnk<=mid) tmp[++tl]=opt[i];
else tmp[++tr]=opt[i];
}
for(int i=L;i<=R;++i) opt[i]=tmp[i];
solve(L,mid),solve(mid+1,R);
}
int main(){
//setIO("input");
scanf("%d%d",&n,&m);
for(int i=1,a;i<=n;++i)
{
scanf("%d",&a);
opt[++idx].x=i;
opt[idx].y=a;
opt[idx].z=1;
opt[idx].kind=1;
opt[idx].rnk=idx;
place[a]=i;
tree.add(a,1);
ans[1]+=i-tree.ask(a);
}
for(int i=1;i<=n;++i) tree.add(i,-1);
for(int i=1,a;i<=m;++i){
scanf("%d",&a);
opt[++idx].x=place[a];
opt[idx].y=n;
opt[idx].z=-1;
opt[idx].kind=2;
opt[idx].rnk=idx;
opt[idx].id=i+1; opt[++idx].x=n;
opt[idx].y=a;
opt[idx].z=-1;
opt[idx].kind=2;
opt[idx].rnk=idx;
opt[idx].id=i+1; opt[++idx].x=place[a];
opt[idx].y=a;
opt[idx].z=2;
opt[idx].kind=2;
opt[idx].rnk=idx;
opt[idx].id=i+1; opt[++idx].x=place[a];
opt[idx].y=a;
opt[idx].z=-1;
opt[idx].kind=1;
opt[idx].rnk=idx;
}
sort(opt+1,opt+1+idx,cmp);
solve(1,idx);
for(int i=2;i<=m;++i) ans[i]+=ans[i-1];
for(int i=1;i<=m;++i) printf("%lld\n",ans[i]);
return 0;
}
P3157 [CQOI2011]动态逆序对 CDQ分治的更多相关文章
- 洛谷 P3157 [CQOI2011]动态逆序对 | CDQ分治
题目:https://www.luogu.org/problemnew/show/3157 题解: 1.对于静态的逆序对可以用树状数组做 2.我们为了方便可以把删除当成增加,可以化动为静 3.找到三维 ...
- LUOGU P3157 [CQOI2011]动态逆序对(CDQ 分治)
传送门 解题思路 cdq分治,将位置看做一维,修改时间看做一维,权值看做一维,然后就转化成了三维偏序,用排序+cdq+树状数组.注意算删除贡献时要做两次cdq,分别算对前面和后面的贡献. #inclu ...
- P3157 [CQOI2011]动态逆序对 (CDQ解决三维偏序问题)
P3157 [CQOI2011]动态逆序对 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任 ...
- [BZOJ3295][Cqoi2011]动态逆序对 CDQ分治&树套树
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j,且 ...
- 【BZOJ3295】[Cqoi2011]动态逆序对 cdq分治
[BZOJ3295][Cqoi2011]动态逆序对 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依 ...
- bzoj3295: [Cqoi2011]动态逆序对(cdq分治+树状数组)
3295: [Cqoi2011]动态逆序对 题目:传送门 题解: 刚学完cdq分治,想起来之前有一道是树套树的题目可以用cdq分治来做...尝试一波 还是太弱了...想到了要做两次cdq...然后伏地 ...
- BZOJ3295 [Cqoi2011]动态逆序对 —— CDQ分治
题目链接:https://vjudge.net/problem/HYSBZ-3295 3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 1 ...
- [CQOI2011]动态逆序对 CDQ分治
洛谷上有2道相同的题目(基本是完全相同的,输入输出格式略有不同) ---题面--- ---题面--- CDQ分治 首先由于删除是很不好处理的,所以我们把删除改为插入,然后输出的时候倒着输出即可 首先这 ...
- BZOJ 3295: [Cqoi2011]动态逆序对 [CDQ分治]
RT 传送门 首先可以看成倒着插入,求逆序对数 每个数分配时间(注意每个数都要一个时间)$t$,$x$位置,$y$数值 $CDQ(l,r)$时归并排序$x$ 然后用$[l,mid]$的加入更新$[mi ...
随机推荐
- nyoj--1237--最大岛屿(dfs+数据处理)
最大岛屿 时间限制:1000 ms | 内存限制:65535 KB 难度: 描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比海盗,你知道吧?杰克船长驾驶着自己的的战 ...
- 1.future线程通信
#include <future> #include<iostream> #include <thread> #include <thread> #in ...
- vue项目中设置全局引入scss,使每个组件都可以使用变量
在Vue项目中使用scss,如果写了一套完整的有变量的scss文件.那么就需要全局引入,这样在每个组件中使用. 可以在mian.js全局引入,下面是使用方法. 1: 安装node-sass.sass- ...
- 洛谷P1339 [USACO09OCT]热浪Heat Wave(最短路)
题目描述 The good folks in Texas are having a heatwave this summer. Their Texas Longhorn cows make for g ...
- IOS设备获取崩溃日志的办法
除了用xcode 的devices功能获取之外,在windows下面也是可以获取的.首先安装itools.下载地址: http://www.itools.cn/ 安装好后将设备(iphone或ipad ...
- Sed Awk 日常使用总结
Sed命令语法sed [option] {sed-commands}{input-file}sed首先从input-file中读取第一行,然后执行所有的sed-commands:再读取第二行,执行所有 ...
- springmvc两种非注解的处理器适配器
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...
- STM8S103之中断优先级设置
STM8S的中断由中断控制器(ITC)控制.STM8所有IO都支持中断,分为PA~PE 5个组,每组IO对应一个中断服务函数(也就是每组IO只有一个向量).STM8没有专门的中断状态寄存器,所以只能通 ...
- C语言中的作用域、链接属性与存储属性
C语言中的作用域.链接属性与存储属性 一.作用域(scope) 代码块作用域 表示{}之间的区域,下例所示,a可以在不同的代码块里面定义. #include<stdio.h> int ma ...
- Zookeeper入门-Linux环境下异常ConnectionLossException解决
实际项目开发中,用的是Linux环境. 中午突然断电,死活连不上Zookeeper,最终发现是需要关闭防火墙. 看日志,报错如下: Exception in thread "mai ...