洛谷 P3810 【模板】三维偏序(陌上花开) (cdq分治模板)
在solve(L,R)中,需要先分治solve两个子区间,再计算左边区间修改对右边区间询问的贡献。
注意,计算额外的贡献时,两子区间各自内部的顺序变得不再重要(不管怎么样左边区间的都发生在右边之前),于是就少了一维
https://www.lydsy.com/JudgeOnline/problem.php?id=3262
https://www.luogu.org/problemnew/show/P3810
此题每个操作既是修改又是查询
对于此题,先按一维排序,在solve(L,R)中先solve两个子区间,然后把L到R的操作按二维排序(由于cdq分治类似归并的特性此时两个子区间内部二维都是有序的,可以直接二路归并),然后就是一个对二、三维求逆序对的过程(只不过只有归并前在第一个区间内的修改生效,归并前在第二个区间内的查询要更新答案)
可以记一下每个元素在按第一维排序后的编号(以下代码中q[i].num),来判断它归并前是哪个区间里的
注意:此题第一维相同的实际并不存在顺序关系,理应同时处理然后同时计算贡献,但排序后它们间总是要存在一个特定顺序的,所以要加一些奇怪的特判
具体的话:首先一开始排序的时候三个关键字都要依次考虑(而不是只考虑第一维),这样可以保证排序后大部分情况下后面的不会对前面产生贡献
上面还漏考虑了完全相等的三元组,如果它们存在则后面也会对前面产生贡献。因此只要在开始solve前补上这些后面对前面产生的贡献即可
归并可以简化为
merge(q+lp,q+mid+,q+mid+,q+rp+,tmp+lp);
copy(tmp+lp,tmp+rp+,q+lp);
或
inplace_merge(q+lp,q+mid+,q+rp+);
#include<cstdio>
#include<algorithm>
using namespace std;
struct Q
{
int a,b,c,ans,num;
}q[],tmp[];
int n,k;
bool c1(const Q &a,const Q &b) {return a.a<b.a||(a.a==b.a&&a.b<b.b)||(a.a==b.a&&a.b==b.b&&a.c<b.c);}
bool operator<(const Q &a,const Q &b) {return a.b<b.b||(a.b==b.b&&a.num<b.num);}
bool operator==(const Q &a,const Q &b) {return a.a==b.a&&a.b==b.b&&a.c==b.c;}
int dat[];
const int N=;
#define lowbit(x) ((x)&(-x))
void addx(int pos,int d)
{
for(;pos<=N;pos+=lowbit(pos)) dat[pos]+=d;
}
int sum(int pos)
{
int ans=;
for(;pos>;pos-=lowbit(pos)) ans+=dat[pos];
return ans;
}
int num[];
void solve(int lp,int rp)
{
if(lp==rp) return;
int mid=lp+(rp-lp)/;
solve(lp,mid);solve(mid+,rp);
int k=lp-,i,j;
for(i=lp,j=mid+;i<=mid&&j<=rp;)
{
++k;
if(q[i]<q[j]) tmp[k]=q[i++];
else tmp[k]=q[j++];
}
while(i<=mid) tmp[++k]=q[i++];
while(j<=rp) tmp[++k]=q[j++];
for(i=lp;i<=rp;i++) q[i]=tmp[i];
for(i=lp;i<=rp;i++)
{
if(q[i].num<=mid) addx(q[i].c,);
else q[i].ans+=sum(q[i].c);
}
for(i=lp;i<=rp;i++)
if(q[i].num<=mid)
addx(q[i].c,-);
}
int main()
{
int i,j,t,tt=;
scanf("%d%d",&n,&t);
for(i=;i<=n;i++) scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].c);
sort(q+,q+n+,c1);
for(i=;i<=n;i++)
{
tt++;
if(i==n||!(q[i]==q[i+]))
{
for(j=i-tt+,t=tt-;j<=i;j++) q[j].ans+=t,--t;
tt=;
}
}
for(i=;i<=n;i++) q[i].num=i;
solve(,n);
for(i=;i<=n;i++) num[q[i].ans]++;
for(i=;i<n;i++) printf("%d\n",num[i]);
return ;
}
来看看cdq分治的限制
1.题目允许离线操作
2.修改操作对询问的贡献独立,且修改之间互不影响
3.修改对答案的贡献是确定的,与判定标准无关
洛谷 P3810 【模板】三维偏序(陌上花开) (cdq分治模板)的更多相关文章
- BZOJ3262:陌上花开 & 洛谷3810:三维偏序——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=3262 https://www.luogu.org/problemnew/show/3810 Desc ...
- BZOJ3262: 陌上花开(三维偏序,CDQ分治)
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美 ...
- HDU 5618 Jam's problem again(三维偏序,CDQ分治,树状数组,线段树)
Jam's problem again Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- 洛谷P1393 动态逆序对(CDQ分治)
传送门 题解 听别人说这是洛谷用户的双倍经验啊……然而根本没有感觉到……因为另外的那题我是用树状数组套主席树做的……而且莫名其妙感觉那种方法思路更清晰(虽然码量稍稍大了那么一点点)……感谢Candy大 ...
- hdu5618 (三维偏序,cdq分治)
给定空间中的n个点,问每个点有多少个点小于等于自己. 先来分析简单的二维的情况,那么只要将x坐标排序,那么这样的问题就可以划分为两个子问题,,这样的分治有一个特点,即前一个子问题的解决是独立的,而后一 ...
- 洛谷 P3157 [CQOI2011]动态逆序对 | CDQ分治
题目:https://www.luogu.org/problemnew/show/3157 题解: 1.对于静态的逆序对可以用树状数组做 2.我们为了方便可以把删除当成增加,可以化动为静 3.找到三维 ...
- 洛谷P3157 动态逆序对 [CQOI2011] cdq分治
正解:cdq分治 解题报告: 传送门! 长得有点像双倍经验还麻油仔细看先放上来QwQ! 这题首先想到的就直接做逆序对,然后记录每个点的贡献,删去就减掉就好 但是仔细一想会发现布星啊,如果有一对逆序对的 ...
- 【洛谷P4093】 [HEOI2016/TJOI2016]序列 CDQ分治+动态规划
你发现只会改变一个位置,所以可以直接进行dp 具体转移的话用 CDQ 分治转移就好了~ #include <bits/stdc++.h> #define N 100006 #define ...
- 洛谷P3810 陌上花开 CDQ分治(三维偏序)
好,这是一道三维偏序的模板题 当然没那么简单..... 首先谴责洛谷一下:可怜的陌上花开的题面被无情的消灭了: 这么好听的名字#(滑稽) 那么我们看了题面后就发现:这就是一个三维偏序.只不过ans不加 ...
- BZOJ3262/洛谷P3810 陌上花开 分治 三维偏序 树状数组
原文链接http://www.cnblogs.com/zhouzhendong/p/8672131.html 题目传送门 - BZOJ3262 题目传送门 - 洛谷P3810 题意 有$n$个元素,第 ...
随机推荐
- mysql使用“.frm”文件恢复表结构
mysql创建每张表后都会在“mysql安装目录/data/数据库名/”目录下创建一个“表名.frm”文件. 该.frm文件并不能直接打开,但是它可以帮助你恢复你的表结构~~ 具体操作如下: 我现在准 ...
- android keyEvent
http://developer.android.com/reference/android/view/KeyEvent.html
- 新装Linux系统没有网卡驱动的解决办法和步骤
Linux下查看网卡驱动和版本信息 - CSDN博客 https://blog.csdn.net/guyan1101/article/details/72770424/ 检查网卡是否加载 - Linu ...
- CodeForces 24D Broken robot(期望+高斯消元)
CodeForces 24D Broken robot 大致题意:你有一个n行m列的矩形板,有一个机器人在开始在第i行第j列,它每一步会随机从可以选择的方案里任选一个(向下走一格,向左走一格,向右走一 ...
- UISegmentedControl方法与属性的总结
SegmentedControl又被称作分段控制器,是IOS开发中经常用到的一个UI控件. 初始化方法:传入的数组可以是字符串也可以是UIImage对象的图片数组 - (instancetype)in ...
- 编译android内核和文件系统,已经安装jdk,提示build/core/config.mk:268: *** Error: could not find jdk tools.jar
1:确保安装jdk,如果没有安装请移布:http://www.cnblogs.com/jiuyueguang/p/3156621.html 2:如果已经安装了jdk,还是提示此错误, 解决方法 请确保 ...
- HDU2612 Find a way —— BFS
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2612 Find a way Time Limit: 3000/1000 MS (Java/Others ...
- IDEA中使用git详细步骤
1.idea中配置git 设置 版本控制 git 配置git的执行路径(git.ext) 2.把项目推送到远程仓库(码云项目管理) a.在码云创建一个项目 b.复制项目的URL c.找到要上传到码云管 ...
- (转)Linux下 SVN客户端安装
原地址:http://rtxbc.iteye.com/blog/860092 今天有现场程序连svn服务器一直有异常,于是在现场linux下安装svn client来直接测试,看问题原因: 一:安装s ...
- I.MX6 NXP git 仓库
/************************************************************************* * I.MX6 NXP git 仓库 * 说明: ...