BZOJ 2141 排队 (CDQ分治)
【BZOJ2141】排队
这道题和动态逆序对比较像(BZOJ-3295 没做过的同学建议先做这题),只是删除操作变成了交换。解法:交换操作可以变成删除加插入操作,那么这题就变成了 (时间,位置,值)的三维偏序问题,考虑用CDQ分治解决:时间排序,位置分治,值树状数组。
但是这里要特别注意的是:本题因为有多个插入删除操作,所以多能会有多个操作的位置是相同的,但是逆序对要求的是位置比它小/大,值比它大/小的对,就是位置相等的不能算贡献。所以我们对CDQ分治的第二维的归并顺序就有讲究:必须是位置严格小于才放到左边然后插入树状数组,也就是说左边位置必须严格小于右边位置才算贡献。
其实这样说也不太对,(蒟蒻开始口胡)应该说CDQ分治的本质是:对于一个询问,它的答案就是所有比它早的修改对这个询问产生的影响累加的结果。也就是说其实分治的顺序并不是十分重要,只要达到了上面这个目标即可,但是往往我们为了方便统计答案会修改分治顺序使得这样做利于统计答案。举个例子就是像这题哪怕把分治顺序改为return x<rhs.x || x==rhs.x && z<rhs.z;只要把统计答案改为Q[p].x<Q[q].x其实也是OK的,只不过会使得分治和统计答案分开了而已。
细节见代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+;
int n,m,qid,a[N],b[N],ans[N];
struct rec{
int x,y,z,aid; //位置,插入/删除,值,答案下标
bool operator < (const rec &rhs) const {
return x<rhs.x;
}
}Q[N],tmp[N]; int sum[N];
void update(int x,int v) {
for (;x<=n;x+=x&-x) sum[x]+=v;
}
int query(int x) {
int ret=;
for (;x;x-=x&-x) ret+=sum[x];
return ret;
} void CDQ(int l,int r) {
if (l>=r) return;
int mid=l+r>>;
CDQ(l,mid); CDQ(mid+,r);
int p=l,q=mid+,o=l-;
while (p<=mid || q<=r) //归并排序结果
if (q>r || p<=mid && Q[p]<Q[q]) tmp[++o]=Q[p++]; else tmp[++o]=Q[q++]; p=l; q=mid+;
while (p<=mid || q<=r) //正向算逆序对
if (q>r || p<=mid && Q[p]<Q[q]) update(Q[p].z,Q[p].y),p++;
else ans[Q[q].aid]+=Q[q].y*(query(n)-query(Q[q].z)),q++;
for (int i=l;i<=mid;i++) update(Q[i].z,-Q[i].y); p=mid; q=r;
while (p>=l || q>mid) //反向算逆序对
if (q<=mid || p>=l && Q[q]<Q[p]) update(Q[p].z,Q[p].y),p--;
else ans[Q[q].aid]+=Q[q].y*(query(Q[q].z-)),q--;
for (int i=l;i<=mid;i++) update(Q[i].z,-Q[i].y); for (int i=l;i<=r;i++) Q[i]=tmp[i];
} int main()
{
cin>>n;
for (int i=;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
sort(b+,b+n+);
int t=unique(b+,b+n+)-(b+);
for (int i=;i<=n;i++) a[i]=lower_bound(b+,b+t+,a[i])-b;
for (int i=;i<=n;i++) Q[++qid]=(rec){i,,a[i],}; cin>>m;
for (int i=;i<=m;i++) {
int x,y; scanf("%d%d",&x,&y);
Q[++qid]=(rec){x,-,a[x],i};
Q[++qid]=(rec){x,,a[y],i};
Q[++qid]=(rec){y,-,a[y],i};
Q[++qid]=(rec){y,,a[x],i};
swap(a[x],a[y]);
} CDQ(,qid);
for (int i=;i<=m;i++) {
if (i) ans[i]+=ans[i-];
printf("%d\n",ans[i]);
}
return ;
}
BZOJ 2141 排队 (CDQ分治)的更多相关文章
- BZOJ 2141: 排队 [CDQ分治]
题意: 交换序列中两个元素,求逆序对 做分块做到这道题...一看不是三维偏序嘛.... 作为不会树套树的蒟蒻就写CDQ分治吧.... 对时间分治...x排序...y树状数组... 交换拆成两个插入两个 ...
- bzoj 2141 : 排队 (cdq分治+bit)
链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2141 思路: 其实就是求动态逆序对...cdq降维,用树状数组前后求两遍逆序对就好了 切水 ...
- [BZOJ 3456]城市规划(cdq分治+FFT)
[BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...
- [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)
[BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...
- bzoj 4237 稻草人 - CDQ分治 - 单调栈
题目传送门 传送点I 传送点II 题目大意 平面上有$n$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...
- bzoj 3262 陌上花开 - CDQ分治 - 树状数组
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- bzoj 2141: 排队
2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MB Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我, ...
- Bzoj 2141: 排队 分块,逆序对,树状数组
2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MBSubmit: 1310 Solved: 517[Submit][Status][Discuss] D ...
- bzoj 2141 : 排队 分块
题目链接 2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MBSubmit: 1169 Solved: 465[Submit][Status][Discu ...
随机推荐
- 【leetcode】1033. Moving Stones Until Consecutive
题目如下: Three stones are on a number line at positions a, b, and c. Each turn, you pick up a stone at ...
- SQLite和MySQL数据库的差别与应用
简单来说,SQLITE功能简约.小型化,追求最大磁盘效率:MYSQL功能全面,综合化.追求最大并发效率.假设仅仅是单机上用的,数据量不是非常大.须要方便移植或者须要频繁读/写磁盘文件的话.就用SQLi ...
- 解决IDEA输入法输入中文候选框不显示问题
本机环境为: 系统: win7 jdk版本:jdk1.8.0_65 idea版本:2017.2.3 解决方法:关掉idea,进入idea的安装目录找到jre64文件夹重命名为j ...
- spring-cloud zuul网关
API Gateway 是随着微服务(Microservice)这个概念一起兴起的一种架构模式,它用于解决微服务过于分散,没有一个统一的出入口进行流量管理的问题. 使用 Zuul 实现 API Gat ...
- day19—纯CSS实现菜单列表下框跟随效果
转行学开发,代码100天——2018-04-04 今天看到一篇介绍利用CSS实现列表下跟随效果的设计文章,如下图,当鼠标滑过列表项时,要求该项内容下的黑色下边框线实现同方向的跟随移动. 其中,列表内容 ...
- day10—jQuery初步实践,关于菜单
转行学开发,代码100天——2018-03-26 今天是本人写开发记录方面博客的第10天了,不知不觉已经涉及到jQuery框架的学习了. 第一次熬夜写前端代码还是两年前,不过中途放弃了,学的东西也日渐 ...
- 【GIS数据格式】ArcInfo Binary Grid Format
最近在修改项目时发现有些提取的坡度数据在参与了下一步计算后会出错,仔细跟了代码之后发现AE生成的坡度数据和其他一些分析后的栅格都被存储为.adf文件.说起惭愧,并不了解这是什么数据,由于下层算法使用G ...
- linux新建用户并修改提示符
1 新建用户 # useradd –d /home/ap/testapp -m testapp 此命令创建了一个用户testapp ,其中-d和-m选项用来为登录名testapp 产生一个主目录/ho ...
- UGUI OnValueChanged 动态参数指定
在选择方法的时候注意,选择最上面的动态参数的方法.
- ubuntu搭建jdk+jenkins
第一步,安装jdk(如果已安装,直接进行第二步) 1.下载 jdk-8u172-linux-x64.tar.gz 点此下载 2.解压 tar -zxvf jdk-8u172-linux ...