在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分治模板)的更多相关文章

  1. BZOJ3262:陌上花开 & 洛谷3810:三维偏序——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=3262 https://www.luogu.org/problemnew/show/3810 Desc ...

  2. BZOJ3262: 陌上花开(三维偏序,CDQ分治)

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美 ...

  3. 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 ...

  4. 洛谷P1393 动态逆序对(CDQ分治)

    传送门 题解 听别人说这是洛谷用户的双倍经验啊……然而根本没有感觉到……因为另外的那题我是用树状数组套主席树做的……而且莫名其妙感觉那种方法思路更清晰(虽然码量稍稍大了那么一点点)……感谢Candy大 ...

  5. hdu5618 (三维偏序,cdq分治)

    给定空间中的n个点,问每个点有多少个点小于等于自己. 先来分析简单的二维的情况,那么只要将x坐标排序,那么这样的问题就可以划分为两个子问题,,这样的分治有一个特点,即前一个子问题的解决是独立的,而后一 ...

  6. 洛谷 P3157 [CQOI2011]动态逆序对 | CDQ分治

    题目:https://www.luogu.org/problemnew/show/3157 题解: 1.对于静态的逆序对可以用树状数组做 2.我们为了方便可以把删除当成增加,可以化动为静 3.找到三维 ...

  7. 洛谷P3157 动态逆序对 [CQOI2011] cdq分治

    正解:cdq分治 解题报告: 传送门! 长得有点像双倍经验还麻油仔细看先放上来QwQ! 这题首先想到的就直接做逆序对,然后记录每个点的贡献,删去就减掉就好 但是仔细一想会发现布星啊,如果有一对逆序对的 ...

  8. 【洛谷P4093】 [HEOI2016/TJOI2016]序列 CDQ分治+动态规划

    你发现只会改变一个位置,所以可以直接进行dp 具体转移的话用 CDQ 分治转移就好了~ #include <bits/stdc++.h> #define N 100006 #define ...

  9. 洛谷P3810 陌上花开 CDQ分治(三维偏序)

    好,这是一道三维偏序的模板题 当然没那么简单..... 首先谴责洛谷一下:可怜的陌上花开的题面被无情的消灭了: 这么好听的名字#(滑稽) 那么我们看了题面后就发现:这就是一个三维偏序.只不过ans不加 ...

  10. BZOJ3262/洛谷P3810 陌上花开 分治 三维偏序 树状数组

    原文链接http://www.cnblogs.com/zhouzhendong/p/8672131.html 题目传送门 - BZOJ3262 题目传送门 - 洛谷P3810 题意 有$n$个元素,第 ...

随机推荐

  1. 二分法和牛顿迭代实现开根号函数:OC的实现

    最近有人贴出BAT的面试题,题目链接. 就是实现系统的开根号的操作,并且要求一定的误差,其实这类题就是两种方法,二分法和牛顿迭代,现在用OC的方法实现如下: 第一:二分法实现 -(double)sqr ...

  2. Android - 监听Activity点击无效

    监听Activity点击无效 本文地址: http://blog.csdn.net/caroline_wendy Activity须要先在Manifest注冊,才干在app中使用; Manifest: ...

  3. MySQL 权限生效

    用GRANT.REVOKE或SET PASSWORD对授权表施行的修改会立即被服务器注意到. 如果你手工地修改授权表(使用INSERT.UPDATE等等),你应该执行一个FLUSH PRIVILEGE ...

  4. git format-patch 用法

    git format-patch HEAD^ # git format-patch -s 1bbe3c8c197a35f79bfddaba099270a2e54ea9c7 please replace ...

  5. YTU 2455: Pefect 数字

    2455: Pefect 数字 时间限制: 1 Sec  内存限制: 128 MB 提交: 749  解决: 146 题目描述 小明和小林做数字游戏,他们的游戏规则如下: 小明说出一个数字n,小林说出 ...

  6. 没有该栏目数据可能缓存文件(data/cache/inc_catalog_base.inc)没有更新请检查是否有写入权限

    dedecms系统搬家后或在系统还原后,重新更新栏目或文件的时候,有时会出现这样的错误提示:没有该栏目数据可能缓存文件(data/cache/inc_catalog_base.inc)没有更新请检查是 ...

  7. MYSQL初级学习笔记四:查询数据的操作DQL(SELECT基本形式)(26-35)

    知识点六:查询数据的操作DQL(SELECT基本形式)(26-35) CREATE DATABASE IF NOT EXISTS cms DEFAULT CHARACTER SET utf8; USE ...

  8. html5--6-9 CSS选择器6--伪类选择器

    html5--6-9 CSS选择器6--伪类选择器 实例 @charset="UTF-8"; /*:root{background: green}*/ /*li:first-chi ...

  9. Mysql语句示例

    Mysql语句示例 最常用 sql 语句总结 前言 Mysql 是数据库开发使用的主要平台之一.sql 的学习掌握与使用是数据库开发的基础,此处展示详细sql 语句的写法,及各种功能下的 sql 语句 ...

  10. I.MX6 eMMC分区挂载

    /********************************************************************* * I.MX6 eMMC分区挂载 * 说明: * 如果想要 ...