四维偏序 CDQ套CDQ
对CDQ深一步的理解
昨天做了一道CDQ,看了一堆CDQ可做的题,今天又做了一道四维偏序
感觉对CDQ的理解又深了一点,故来写一写现在自己对于CDQ的理解
CDQ其实就是实现了这样的一个问题的转化:
\(a_{l} < a_{l+1} < ... < a_r => (a_l,a_{l+1},...,a_{mid}) \text{都小于} (a_{mid+1},a{mid+2},...,a_r)\)
然后我们就知道这时候左边所有的点都一定小于右边的点
在四维偏序的算法中,那就是左边的点可以对右边的点做出贡献(仅在当前维度下)
这样就强行消除了一个维度的限制.
四维偏序
题目大意
给定一个有\(n\)个元素的序列,元素编号为\(1~n\),每个元素有三个属性\(a,b,c\),求序列中满足\(i<j\)且\(a_i<a_j\)且\(b_i<b_j\)且\(c_i<c_j\)的数对\((i,j)\)的个数。
题解
我们把下标也看作一个维度,那么这就是个四维偏序
我们在下标的维度上CDQ
然后记录每个元素在第一次CDQ中是较小的还是较大的.
因为只有较小的元素才能对较大的元素做出贡献
只有较大的元素才能接受较小的元素的影响.
所以我们处理出来后这就变成了一个三维偏序
所以我们在对这个序列(CDQ+扫描线+树状数组)求三维偏序即可
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
	x=0;char ch;bool flag = false;
	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 50010;
struct Node{
	int a,b,c;
	bool is_sm;
	Node(){a=b=c=is_sm = 0;}
}a[maxn],tmp1[maxn],tmp2[maxn];
int c[maxn],n,init_tmp[maxn],ans=0;
#define lowbit(x) (x&-x)
inline void modify(int x,int y){
	for(;x<=n;x+=lowbit(x)) c[x] += y;
}
inline int query(int x){
	int ret = 0;
	for(;x;x-=lowbit(x)) ret += c[x];
	return ret;
}
void solve2(int l,int r){
	if(l == r) return ;
	int mid = l+r >> 1;
	solve2(l,mid);solve2(mid+1,r);
	int i = l,j = mid+1,k = l;
	Node *a = tmp1,*tmp = tmp2;
	init_tmp[0] = 0;
	while(i <= mid || j <= r){
		if((j > r) || (i <= mid && a[i].b < a[j].b)){
			if( a[i].is_sm){
				modify(a[i].c,1);
				init_tmp[++init_tmp[0]] = i;
			}tmp[k++] = a[i++];
		}else{
			if(!a[j].is_sm){
				ans += query(a[j].c);
			}tmp[k++] = a[j++];
		}
	}for(int i = 1;i<=init_tmp[0];++i) modify(a[init_tmp[i]].c,-1);
	copy(tmp+l,tmp+r+1,a+l);
}
void solve1(int l,int r){
	if(l == r) return ;
	int mid = l+r >> 1;
	solve1(l,mid);solve1(mid+1,r);
	int i = l,j = mid+1,k = l;
	Node *tmp = tmp1;
	while(i <= mid || j <= r){
		if((j > r) || (i <= mid && a[i].a < a[j].a)){
			(tmp[k++] = a[i++]).is_sm = true;
		}else (tmp[k++] = a[j++]).is_sm = false;
	}
	copy(tmp+l,tmp+r+1,a+l);
	solve2(l,r);
}
int main(){
//	freopen("partial_order.in","r",stdin);
//	freopen("partial_order.out","w",stdout);
	read(n);
	for(int i=1;i<=n;++i) read(a[i].a);
	for(int i=1;i<=n;++i) read(a[i].b);
	for(int i=1;i<=n;++i) read(a[i].c);
	solve1(1,n);printf("%d\n",ans);
	getchar();getchar();
	return 0;
}
												
											四维偏序 CDQ套CDQ的更多相关文章
- cogs2479 偏序(CDQ套CDQ)
		
题目链接 思路 四维偏序 \(CDQ\)套\(CDQ\),第一维默认有序.第二维用第一个\(CDQ\)变成有序的.并且对每个点标记上第一维属于左边还是右边.第二个\(CDQ\)处理第三维,注意两个\( ...
 - [HZOI 2016] 偏序(CDQ套CDQ)
		
传送门 思路: 就是cdq套cdq的模板题 #include <bits/stdc++.h> using namespace std; typedef long long ll; cons ...
 - HDU - 5126: stars (求立方体内点数 CDQ套CDQ)
		
题意:现在给定空空的三维平面,有加点操作和询问立方体点数. 思路:考虑CDQ套CDQ.复杂度是O(NlogN*logN*logN),可以过此题. 具体的,这是一个四维偏序问题,4维分别是(times, ...
 - HDU5126---stars (CDQ套CDQ套 树状数组)
		
题意:Q次操作,三维空间内 每个星星对应一个坐标,查询以(x1,y1,z1) (x2,y2,z2)为左下顶点 .右上顶点的立方体内的星星的个数. 注意Q的范围为50000,显然离散化之后用三维BIT会 ...
 - 【教程】CDQ套CDQ——四维偏序问题
		
前言 上一篇文章已经介绍了简单的CDQ分治,包括经典的二维偏序和三维偏序问题,还有带修改和查询的二维/三维偏序问题.本文讲介绍多重CDQ分治的嵌套,即多维偏序问题. 四维偏序问题 给定N( ...
 - COGS 2479. [HZOI 2016] 偏序 (CDQ套CDQ)
		
传送门 解题思路 四维偏序问题,模仿三维偏序,第一维排序,第二维CDQ,最后剩下二元组,发现没办法处理,就继续嵌套CDQ分治.首先把二元组的左右两边分别打上不同的标记,因为统计答案时只统计左边对右边的 ...
 - hdu 5126 stars (四维偏序,离线,CDQ套CDQ套树状数组)
		
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5126 思路:支持离线,那么我们可以用两次CDQ分治使四维降为二维,降成二维后排个序用树状数组维护下就好 ...
 - HDU 5126 stars 4维偏序, CDQ套CDQ
		
题目传送门 题意:在一个星空中,按着时间会出现一些点,现在john想知道,在某个时间内有多少个星星是的坐标是满足条件的.(x1<=x<=x2, y1 <= y <= y2, z ...
 - COGS 2479. [HZOI 2016]偏序 [CDQ分治套CDQ分治 四维偏序]
		
传送门 给定一个有n个元素的序列,元素编号为1~n,每个元素有三个属性a,b,c,求序列中满足i<j且ai<aj且bi<bj且ci<cj的数对(i,j)的个数. 对于100%的 ...
 
随机推荐
- 将C#文档注释生成.chm帮助文档(转)
			
由于最近需要把以前的一个项目写一个文档,但一时又不知道写成怎样的,又恰好发现了可以生成chm的工具,于是乎我就研究了下,感觉还不错,所以也给大家分享下.好了,不多废话,下面就来实现一下吧. 生成前的准 ...
 - client交互技术简单介绍
			
随着网络应用的不断丰富,client交互技术也如雨后春笋一般,遍地开花. 正是这些技术的支持,我们的互联网世界变得更加丰富多彩.一个浏览器上.不用说是简单的动画效果,就是一个Office应用也能顺畅的 ...
 - asp.net core 系列之Reponse caching之cache in-memory (2)
			
这篇文章(主要翻译于官网,水平有限,见谅)讲解asp.net core 中的 Cache in-memory (内存缓存). Cache in-memory in ASP.NET Core Cachi ...
 - A20地址线问题
			
[0]README text description from Zhaojiong's perfect analysis of Linux kernel . [1]A20地址线问题(干货来了) 198 ...
 - Java 并发随身记(一)之 Unsafe类
			
最近在看Java并发相关的内容,需要自己整理整理,不然就生疏了.工作2年多,工作时一般注都是框架.消息这些内容,对基础内容比较忽视.闲话不说,既然是并发内容,首先先复习一下Unsafe的内容吧. Un ...
 - python发布IIS
			
参考文档 https://segmentfault.com/a/1190000008909201 http://blog.51cto.com/anngle/1922041 https://www.cn ...
 - 20179209课后作业之od命令重写
			
一.问题描述: 1 复习c文件处理内容 2 编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能 3. main与其他分开,制作静态库和动态库 4. 编写Makefi ...
 - 利用socket.io实现多人聊天室(基于Nodejs)
			
socket.io简单介绍 在Html5中存在着这种一个新特性.引入了websocket,关于websocket的内部实现原理能够看这篇文章.这篇文章讲述了websocket无到有,依据协议,分析数据 ...
 - python数据分析之:数据加载,存储与文件格式
			
前面介绍了numpy和pandas的数据计算功能.但是这些数据都是我们自己手动输入构造的.如果不能将数据自动导入到python中,那么这些计算也没有什么意义.这一章将介绍数据如何加载以及存储. 首先来 ...
 - 打开蓝牙debug  hci log
			
Android4.2之前抓取hci log都是通过hcidump命令完成的,但是Android4.2 Bluetooth引入了Bluedroid,这是一个新的蓝牙协议栈.所以抓取hci log的方法也 ...