【BZOJ2141】排队(CDQ分治)
【BZOJ2141】排队(CDQ分治)
题面
题解
大部分树套树/主席树这类题目都可以用整体二分/CDQ分治来做。
这题考虑一下,在不考虑修改的情况下
贡献是如何产生的?
我们发现是个二位偏序问题(或者说是一个逆序对修改版本)
现在有了一个修改,那么产生贡献的前提额外增加一个:时间。
既然变成了一个三位偏序问题
考虑\(CDQ\)分治
按照时间分治,块内按照\(x\)排序,考虑左侧对右侧的贡献:
维护当前数字(离散后)的一个值域树状数组
因为贡献有当前点作为左端点和右端点的两部分
所以,按照\(x\)正着加入树状数组一次,反着加入树状数组一次。
就求一下在当前时间之前,产生贡献的值就行了。
但是交换操作很不好办。
我们可以把一个交换操作改成两个删除操作和两个插入操作。
这样就可以交换的问题。
一个额外要注意的问题:排序的时候,如果\(x\)相同,一定还要按照修改的值排序,因为小的值同样可以更新大的值,否则会错。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 22222
#define lb(x) (x&(-x))
inline int read()
{
    RG int x=0,t=1;RG 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;
}
struct Operator{int t,x,y,w,id;}q[MAX<<2],tmp[MAX<<2];
bool operator<(Operator a,Operator b){if(a.x!=b.x)return a.x<b.x;return a.y<b.y;}
int tot,len,S[MAX],a[MAX],n,m,tim;
int c[MAX],ans[MAX];
void add(int x,int w){while(x<=n)c[x]+=w,x+=lb(x);return;}
int getsum(int x){int ret=0;while(x)ret+=c[x],x-=lb(x);return ret;}
void CDQ(int l,int r)
{
	if(l==r)return;
	int mid=(l+r)>>1;
	for(int i=l;i<=r;++i)
		if(q[i].t<=mid)add(q[i].y,q[i].w);
		else ans[q[i].id]+=q[i].w*(getsum(n)-getsum(q[i].y));
	for(int i=l;i<=r;++i)
		if(q[i].t<=mid)add(q[i].y,-q[i].w);
	for(int i=r;i>=l;--i)
		if(q[i].t<=mid)add(q[i].y,q[i].w);
		else ans[q[i].id]+=q[i].w*getsum(q[i].y-1);
	for(int i=l;i<=r;++i)if(q[i].t<=mid)add(q[i].y,-q[i].w);
	int t1=l-1,t2=mid;
	for(int i=l;i<=r;++i)
		if(q[i].t<=mid)tmp[++t1]=q[i];
		else tmp[++t2]=q[i];
	for(int i=l;i<=r;++i)q[i]=tmp[i];
	CDQ(l,mid);CDQ(mid+1,r);
}
int main()
{
	n=read();
	for(int i=1;i<=n;++i)a[i]=S[i]=read();
	sort(&S[1],&S[n+1]);len=unique(&S[1],&S[n+1])-S-1;
	for(int i=1;i<=n;++i)a[i]=lower_bound(&S[1],&S[len+1],a[i])-S;
	for(int i=1;i<=n;++i)q[++tot]=(Operator){++tim,i,a[i],1,0};
	n=len;m=read();
	for(int i=1;i<=m;++i)
	{
		int x=read(),y=read();
		q[++tot]=(Operator){++tim,x,a[y],+1,i};
		q[++tot]=(Operator){++tim,y,a[x],+1,i};
		q[++tot]=(Operator){++tim,x,a[x],-1,i};
		q[++tot]=(Operator){++tim,y,a[y],-1,i};
		swap(a[x],a[y]);
	}
	sort(&q[1],&q[tot+1]);
	CDQ(1,tim);
	printf("%d\n",ans[0]);
	for(int i=1;i<=m;++i)printf("%d\n",ans[i]+=ans[i-1]);
	return 0;
}
【BZOJ2141】排队(CDQ分治)的更多相关文章
- BZOJ 2141: 排队 [CDQ分治]
		题意: 交换序列中两个元素,求逆序对 做分块做到这道题...一看不是三维偏序嘛.... 作为不会树套树的蒟蒻就写CDQ分治吧.... 对时间分治...x排序...y树状数组... 交换拆成两个插入两个 ... 
- [国家集训队]排队 [cdq分治]
		题面 洛谷 和动态逆序对那道题没有什么区别 把一个交换换成两个删除和两个插入 #include <cstdio> #include <cstdlib> #include < ... 
- bzoj 2141 : 排队  (cdq分治+bit)
		链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2141 思路: 其实就是求动态逆序对...cdq降维,用树状数组前后求两遍逆序对就好了 切水 ... 
- BZOJ 2141 排队 (CDQ分治)
		[BZOJ2141]排队 这道题和动态逆序对比较像(BZOJ-3295 没做过的同学建议先做这题),只是删除操作变成了交换.解法:交换操作可以变成删除加插入操作,那么这题就变成了 (时间,位置,值)的 ... 
- 【教程】简易CDQ分治教程&学习笔记
		前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦! CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ... 
- BZOJ 2683 简单题 ——CDQ分治
		[题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ... 
- HDU5618 & CDQ分治
		Description: 三维数点 Solution: 第一道cdq分治...感觉还是很显然的虽然题目不能再傻逼了... Code: /*=============================== ... 
- 初识CDQ分治
		[BZOJ 1176:单点修改,查询子矩阵和]: 1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 200 ... 
- HDU5322 Hope(DP + CDQ分治 + NTT)
		题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5322 Description Hope is a good thing, which can ... 
随机推荐
- Selenium2+python自动化-CSS定位语法
			前言 一些人在使用selenium定位元素时,用的是xpath定位,因为xpath基本能解决定位的需求.css定位往往被忽略掉了,其实css定位也有它的价值,css定位更快,语法更简洁.这一篇css的 ... 
- 【实用】巧用For xml 生成HTML代码
			可以利用SQL的For xml直接生成HTML结构,比如我想生成如下结构: <li> <img src="..."/> <input type=&qu ... 
- animation和transition
			相同点 指定要侦听更改的CSS属性. 设置计时(缓和)功能以改变从一个属性值到另一个属性值的速率 指定持续时间以控制动画或转换所需的时间 以编程方式收听您可以随意执行的动画和特定于转换的事件 可视化C ... 
- [转载]linux+nginx+python+mysql安装文档
			原文地址:linux+nginx+python+mysql安装文档作者:oracletom # 开发包(如果centos没有安装数据库服务,那么要安装下面的mysql开发包) MySQL-devel- ... 
- RetinaNet 迁移学习到自标数据集
			Keras-RetinaNet 在自标数据集 alidq 上训练 detection model RetinaNet 模型部署与环境配置 参考README 数据预处理 数据统计信息: 类别:gun1, ... 
- javascript event对象操作
			js代码: $(".leads_detail").click(function(e){ e = e || event; var t = e.target || e.srcEleme ... 
- react native组件的生命周期
			react native组件的生命周期 一.当页面第一次加载时,会依次调用: constructor() componentWillMount(): 这个函数调用时机是在组件创建,并初始化了状态之后, ... 
- FIsherman丶Team
			小组成员:郝恒杰,洪佳兴,张子祥 组长:郝恒杰 项目:Fisher Job(渔夫兼职) 简介: 我们的产品渔夫兼职是为了解决大学生兼职群体 的痛苦,他们需要一个好的渠道去找一个让自己满意的兼职,但是现 ... 
- C# string 常用方法
			string.ToString().Contains() String str="abcd" str.ToString().Contains("a"); //t ... 
- Alpha 冲刺(7/10)
			队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭鸭鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 学习MSI.CUDA 试运行软件并调试 ... 
