在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. 项目Beta冲刺(团队4/7)

    项目Beta冲刺(团队4/7) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标: 完成项目Beta版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 陈宇 ...

  2. 字符串函数---strcat()与strncat具体解释及实现

    一.strcat()与strncat() strcat():strcat(dest,src);        strcat把src所指向的字符加入到dest结尾处(覆盖原dest结尾处的'\0').并 ...

  3. V-Play 文档翻译 Page

    V-Play 文档翻译 Page 翻译:qyvlik 应用的一个页面. VPlayApps 1.0 Inherits: MouseArea Inherited By: ListPage 属性 Item ...

  4. 设计模式学习笔记——Decorator装饰模式

    装饰模式的作用或动机就是,尽量避免继承,而使用关联.原因是层层继承下来,内容会越来越多,有失控的危险.就扩展性而言,用关联比用继承好.所谓的关联,A使用了B,就叫A关联了B. Component 抽象 ...

  5. PCH in Xcode 6

    本文转载至 http://blog.csdn.net/wbdwsqwwn/article/details/40476151   新建文件 ⌘+N 选择 iOS/Mac -> Other -> ...

  6. xamarin.Android 实现横向滚动导航

    经过一段时间的练习,自己也做了不少的demo和一些小项目,今天就把这些demo分享给大家,也当做笔记记录到自己的博客中. 这次给大家带来的是HorizontalScrollView实现横向滑动,参考博 ...

  7. MapReduce算法形式六:只有Map独自作战

    案例六:Map独自直接输出 之前一直没有用过这个map独自输出的模式,就算是输出一些简单的我也会经过一次reduce输出,但是,发现这个map输出的结果跟我预想的有点不一样,我一直以为shuffle的 ...

  8. numpy计算

    import numpy as np import cv2 from PIL import Image #lenna.jpg # Create a black image #img=np.zeros( ...

  9. 对于iOS 7 隐藏特性和解决之道

    当 iOS7 刚发布的时候,全世界的苹果开发人员都立马尝试着去编译他们的app,接着再花上数月的时间来修复任何出现的故障,甚至重做app.这样的结果,使得人们根本无暇去探究 iOS7 所带来的新东西. ...

  10. bzoj3957: [WF2011]To Add or to Multiply

    gay队牛逼! 我们可以强行拆一下柿子,最终得到的值会是m^k*x+m^k*u(k)*a+m^k-1*u(k-1)*a……m^0*u(0)*a 其中u表示后面有i个m的a有多少个 答案就是k+∑u 枚 ...