【BZOJ-3262】陌上花开 CDQ分治(3维偏序)
3262: 陌上花开
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 1439 Solved: 648
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
3 3 3
2 3 3
2 3 1
3 1 1
3 1 2
1 3 1
1 1 2
1 2 2
1 3 2
1 2 1
Sample Output
1
3
0
1
0
1
0
0
1
HINT
1 <= N <= 100,000, 1 <= K <= 200,000
Source
Solution
by CA
和Mokia一样,考虑排序来处理掉一维,然后另一维分治,第三维套上数据结构
首先按s为第一关键字,c、m第二、三关键字排序,然后c维分治,对m维建树状数组。
CDQ(l,r)表示[l,r]中对任意的[l,r]中的x贡献。所以用[l,mid]更新对[mid+1,r]中各元素的贡献。
对c为第一关键字再排序,然后得到[l,mid],[mid+1,r]都是以c维从小到大排序的,把[l,mid]中的x,[mid+1,r]中的y,所有x.c<=y.c的x在他的m上+1,直到x.c>y.c,然后我们Query(y.m)就能得到对y的贡献
统计完还原。
要注意的是:这样有序的分治,我们发现当存在x、y,满足x.s==y.s&&x.c==y.c&&x.m==y.m时,显然排序时靠前的那个,统计答案时会少一个,所以我们需要在分治前去重,额外记录一个个数即可。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXN 100010
#define MAXK 200010
int N,K,tp,rank[MAXN];
struct FlowersNode
{
int s,c,m,n,id,rk;
bool operator < (const FlowersNode & A) const
{
return s==A.s? (c==A.c? m<A.m:c<A.c):s<A.s;
}
}f[MAXN],F[MAXN];
bool cmp(FlowersNode A,FlowersNode B) {return A.c==B.c? A.m<B.m:A.c<B.c;}
namespace BIT
{
int tree[MAXK];
inline int lowbit(int x) {return x&-x;}
inline void Change(int pos,int D) {for (int i=pos; i<=K; i+=lowbit(i)) tree[i]+=D;}
inline int Query(int pos) {int re=; for (int i=pos; i; i-=lowbit(i)) re+=tree[i]; return re;}
}
using namespace BIT;
void CDQ(int l,int r)
{
if (l==r) {F[l].rk+=F[l].n-; return;}
int mid=(l+r)>>;
CDQ(l,mid); CDQ(mid+,r);
sort(F+l,F+mid+,cmp); sort(F+mid+,F+r+,cmp);
// for (int i=l; i<=r; i++) printf("%d %d %d %d %d\n",F[i].s,F[i].c,F[i].m,F[i].rk,F[i].n);
int pos=l;
for (int i=mid+; i<=r; F[i].rk+=Query(F[i].m),i++)
for (int j=pos; j<=mid && F[j].c<=F[i].c; j++,pos++)
Change(F[j].m,F[j].n);
for (int i=l; i<=pos-; i++) Change(F[i].m,-F[i].n);
sort(F+l,F+r+,cmp);
}
bool compare(FlowersNode A,FlowersNode B) {return (A.s==B.s)&&(A.c==B.c)&&(A.m==B.m);}
int main()
{
N=read(); K=read();
for (int i=; i<=N; i++) f[i].s=read(),f[i].c=read(),f[i].m=read(),f[i].rk=f[i].n=;
sort(f+,f+N+);
for (int i=; i<=N; i++) if (compare(f[i],F[tp])) F[tp].n++; else F[++tp]=f[i];
CDQ(,tp);
for (int i=; i<=tp; i++) rank[F[i].rk]+=F[i].n;
for (int i=; i<=N; i++) printf("%d\n",rank[i]);
return ;
}
【BZOJ-3262】陌上花开 CDQ分治(3维偏序)的更多相关文章
- BZOJ 3262: 陌上花开 (cdq分治,三维偏序)
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; c ...
- BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- bzoj 3262 陌上花开 - CDQ分治 - 树状数组
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- BZOJ 3262 陌上花开 ——CDQ分治
[题目分析] 多维问题,我们可以按照其中一维排序,然后把这一维抽象的改为时间. 然后剩下两维,就像简单题那样,排序一维,树状数组一维,按照时间分治即可. 挺有套路的一种算法. 时间的抽象很巧妙. 同种 ...
- BZOJ 3262 陌上花开 CDQ分治
= =原来复杂度还是nlog^2(n) Orz 被喷了 #include<cstdio> #include<cstdlib> #include<algorithm> ...
- BZOJ 3262: 陌上花开 CDQ
这个题大部分人用了离散然后水之,然而.....作为一只蒟蒻我并没有想到离散,而是直接拿两个区间一个对应n,一个对应k来搞,当然这两个区间是对应的,我把第一维排序,第二维CDQ,第三维树状数组,然而由于 ...
- 陌上花开 HYSBZ - 3262 (CDQ分治)
陌上花开 HYSBZ - 3262 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另 ...
- cdq分治解决三维偏序
问题背景 在三维坐标系中有n个点,坐标为(xi,yi,zi). 定义一个点A比一个点B小,当且仅当xA<=xB,yA<=yB,zA<=zB.问对于每个点,有多少个点比它小.(n< ...
- [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)
[BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...
- 并不对劲的cdq分治解三维偏序
为了反驳隔壁很对劲的太刀流,并不对劲的片手流决定与之针锋相对,先一步发表cdq分治解三维偏序. 很对劲的太刀流在这里-> 参照一.二维偏序的方法,会发现一位偏序就是直接排序,可以看成通过排序使 ...
随机推荐
- Construct Binary Tree from Inorder and Postorder Traversal
Construct Binary Tree from Inorder and Postorder Traversal Given inorder and postorder traversal of ...
- codevs 2491 玉蟾宫
codevs 2491 玉蟾宫 http://codevs.cn/problem/2491/ 题目描述 Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉 ...
- hadoop 2.6全分布安装
环境:centos 6.6 + hadoop2.6 虚拟机:(vmware fusion 7.0.0) 虚拟机hostname / IP地址 master / 192.168.187. ...
- Orchard CMS中如何打包不带源码的模块
在Orchard CMS的官网已经提供了文档说明如何打包,但是如果使用它的打包方式,打好的nuget包是带源代码的.如果是为开源系统写模块,不需要关注源代码是否可见.但是如果是用Orchard CMS ...
- PRML读书会第六章 Kernel Methods(核函数,线性回归的Dual Representations,高斯过程 ,Gaussian Processes)
主讲人 网络上的尼采 (新浪微博:@Nietzsche_复杂网络机器学习) 网络上的尼采(813394698) 9:16:05 今天的主要内容:Kernel的基本知识,高斯过程.边思考边打字,有点慢, ...
- 汤姆大叔的6道javascript编程题题解
看汤姆大叔的博文,其中有篇(猛戳这里)的最后有6道编程题,于是我也试试,大家都可以先试试. 1.找出数字数组中最大的元素(使用Math.max函数) var a = [1, 2, 3, 6, 5, 4 ...
- 发布新博客皮肤red_autumnal_leaves
感谢sevennight为大家精心设计了一款博客皮肤——red_autumnal_leaves! [名称] red_autumnal_leaves[标题] 红叶[设计者] sevennight[简介] ...
- gravity、layout_gravity及orientation
gravity.layout_gravity及orientation 最近在弄一个简单的界面:横向,添加一张准备好的背景图,在界面右边居中放置一个按钮.实现过程中发现对布局的主要属性没有想象中地那么熟 ...
- SDRAM读写一字(上)
SDRAM读写一字 系统设计 SDRAM指令 指令 常量名 CKE CSn RAS CASn WEn 备注 空操作 NOP 1 0 1 1 1 行激活 ACTIVE 1 0 0 1 1 读操作 ...
- [BZOJ2152]聪聪可可(点分治)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2152 分析:裸的点分治,对于每课树,记录t[0],t[1],t[2]表示到当前根节点距 ...