【COGS2479】 HZOI2016—偏序

http://cogs.pro/cogs/problem/problem.php?pid=2479 (题目链接)

题意

  四维偏序。

Solution

  CDQ套CDQ。

细节

  第二次分治不能直接按照mid分离两类数了。

代码

// cogs2479
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483600
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std;

const int maxn=50010;
int n,ans,f[maxn],c[maxn];
struct data {int x,y,z,id,op;}q[maxn],nq[maxn],p[maxn],np[maxn];

bool cmp(data a,data b) {return a.id<b.id;}
bool CMP(data a,data b) {return a.y<b.y;}
int lowbit(int x) {
	return x&-x;
}
void modify(int x,int val) {
	for (int i=x;i<=n;i+=lowbit(i)) c[i]+=val;
}
int query(int x) {
	int res=0;
	for (int i=x;i;i-=lowbit(i)) res+=c[i];
	return res;
}
void solve2(int l,int r) {
	if (l==r) return;
	int mid=(l+r)>>1;
	sort(p+l,p+r+1,CMP);
	solve2(l,mid);solve2(mid+1,r);
	for (int i=l,j=mid+1,k=l;i<=mid || j<=r;) {
		if (j>r || (i<=mid && p[i].id<p[j].id)) {
			if (p[i].op==0) modify(p[i].z,1);
			np[k++]=p[i++];
		}
		else {
			if (p[j].op==1) f[p[j].id]+=query(p[j].z-1);
			np[k++]=p[j++];
		}
	}
	for (int i=l;i<=mid;i++) if (p[i].op==0) modify(p[i].z,-1);
	for (int i=l;i<=r;i++) p[i]=np[i];
}
void solve(int l,int r) {
	if (l==r) {ans+=f[q[l].id];return;}
	int mid=(l+r)>>1,l1=l,l2=mid+1;
	for (int i=l;i<=r;i++) q[i].x<=mid ? nq[l1++]=q[i] : nq[l2++]=q[i];
	for (int i=l;i<=r;i++) q[i]=nq[i];
	solve(l,mid);
	for (int i=l;i<=r;i++) p[i]=q[i],p[i].op=i>mid;
	sort(p+l,p+r+1,cmp);
	solve2(l,r);
	solve(mid+1,r);
}
int main() {
	free("partial_order");
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",&q[i].x);
	for (int i=1;i<=n;i++) scanf("%d",&q[i].y);
	for (int i=1;i<=n;i++) scanf("%d",&q[i].z);
	for (int i=1;i<=n;i++) q[i].id=i;
	solve(1,n);
	printf("%d",ans);
	fclose(stdin);fclose(stdout);
	return 0;
}
时间: 2024-10-13 08:42:58

【COGS2479】 HZOI2016—偏序的相关文章

COGS2479(四维偏序)

题意:给定一个有n个元素的序列,元素编号为1~n,每个元素有三个属性a,b,c,求序列中满足i<j且ai<aj且bi<bj且ci<cj的数对(i,j)的个数. 分析:cdq分治套cdq分治 对于四维偏序,可以先对第一维排序,然后对第一维分治,按照第二维顺序合并 即cdq(l,r)表示分治第一维,然后把这里面的按照第二维的顺序从小到大排序 然后问题就变成了三维偏序,再套一个cdq2(l,r)去更新答案 不过要注意一点很关键的,那就是按照第二维排序后,第一维已经是乱序了 根据cdq分治

BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]

Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb.显然,两朵花可能有同样的属性.需要统计出评出每个等级的花的数量. Input 第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值. 以下N行,每

HDU 5618:Jam&#39;s problem again(CDQ分治+树状数组处理三维偏序)

http://acm.hdu.edu.cn/showproblem.php?pid=5618 题意:-- 思路:和NEUOJ那题一样的.重新写了遍理解了一下,算作处理三维偏序的模板了. 1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 using namespace std; 6 #define INF 0x3f3f3f3f 7 #d

SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治

Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=19929 Description Given a sequence of N pairs of integers, find the length of the longest incre

偏序与全序

偏序设A是一个非空集,P是A上的一个关系,若关系P是自反的.反对称的.和传递的,则称P是集合A上的偏序关系. 即P适合下列条件: (1)对任意的a∈A,(a,a)∈P; (2)若(a,b)∈P且(b,a)∈P,则a=b; (3)若(a,b)∈P,(b,c)∈P,则(a,c)∈P,则称P是A上的一个偏序关系.带偏序关系的集合A称为偏序集或半序集. 若P是A上的一个偏序关系,我们用a≤b来表示(a,b)∈P. 举如下例子说明偏序关系: 1.实数集上的小于等于关系是一个偏序关系. 2.设S是集合,P(

P2433 - 【BZOJ 3262三维偏序】陌上花开------三维偏序

P2433 - [BZOJ 3262三维偏序]陌上花开 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb.显然,两朵花可能有同样的属性.需要统计出评出每个等级的花的数量. Input 第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,

NEUOJ 1702 撩妹全靠魅力值 (三维偏序)

题目链接:http://acm.neu.edu.cn/hustoj/problem.php?id=1702 题目大意:就是问每个人三个属性同时不低于另外几个人....人不分先后 经典的三维偏序问题 解题思路:CDQ分治练手题 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using nam

【三维偏序】【分块】bzoj3262 陌上花开

裸的三维偏序. 对x坐标排序,y.z坐标分块.复杂度O(n*sqrt(n*log(n))).代码很短. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<vector> 5 using namespace std; 6 struct Point{int x,y,z,num;void Read(){scanf("%d%d%d",&x,&

论如何优雅的用bitset来求四维偏序

四维偏序.. 就是给你一个四维集合.再给你一些询问,请你求出a[i].x1<=ask.x1&&a[i].x2<=ask.x2&&a[i].x3<=ask.x3&&a[i].x4<=ask.x4的个数.. 集合大小<=30000 询问个数<=30000 然后怎么做呢?? 其实很简单只要排序+cdq+树状数组套平衡树什么的就行了 qnmd老子不会.. 这时! 神器来了! 那就是bitset! 众所周知,bitset能存一堆二进