初学CDQ分治-NEU1702
关于CDQ分治,首先需要明白分治的复杂度。
T(n) = 2T(n/2)+O(kn), T(n) = O(knlogn)
T(n) = 2T(n/2)+O(knlogn), T(n) = O(knlog^2n)
T(n) = 2T(n/2)+O(k), T(n) = O(kn)
那么我们要处理[l, r]内的询问,我们可以分别处理[l, m]和[m+1, r]的询问,然后以较小的复杂度计算出[l, m]对[m+1, r]的贡献。
最简单的cdq就是三维偏序问题。
两点(x1, y1, z1)和(x2, y2, z2),同时满足x1 < x2, y1 < y2, z1 < z2,则前面的点小于后面的点。
首先按第一维x排序。
则处理的问题变成对于排在前面的点,统计多少个点满足y维与z维同时小于该点。
CDQ分治。
假设已处理出[l, m]与[m+1, r]。对于[m+1, r]内的所有点,我们还要统计[l, m]内有多少个点相比它更小。
对[l, r]按y维排序,对z维用树状数组统计。
扫描一遍排序后的[l, r]。
若该点在排序前属于[l, m],树状数组单点修改;否则该点在排序前属于[m+1, r],统计一次。
复杂度为O(nlognlogn)
CDQ分治算法的核心就在于:去掉时间的限制,将所有查询要求发生的时刻同化,化动态修改为静态查询
(其实对于有些问题来说可以把某一维的限制通过排序看作时间限制然后运用CDQ分治)
这类分治的特殊性在于分治的左右两部分的合并,作用两部分在合并的时候作用是不同的,比如,通过左半部分的影响来更新右半部分,所以分治开始前都要按照某一个关键字排序,然后利用这个顺序,考虑一个区间[l, r]的两部分间的影响。
框架为
void cdq(int l, int r){
if(l == r) return ;
int m = (l+r)/;
cdq(l, m);
cdq(m+, r);
//统计[l, m]对[m+1, r]的贡献。整体排序后统计。
sort(pp+l, pp+r+, yzx);
for(int i = l; i <= r; i++)
if(pp[i].x <= m)
add(pp[i].z, );
else
ans[ pp[i].n ] += sum(pp[i].z);
for(int i = l; i <= r; i++)
if(pp[i].x <= m)
add(pp[i].z, -);
}
题意:一个人的魅力值是相对于周围人来说的,如果他的颜值,内涵和智慧值同时不低于另外一个人,那么他的魅力值就会加1,给你一些人的颜值,内涵,和智慧值,请输出这些人的魅力值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+;
struct p{
int n, x, y, z;
p(){}
p(int n, int x, int y, int z): n(n), x(x), y(y), z(z){}
bool operator <(const p& A) const{
if(x != A.x) return x < A.x;
return y != A.y? y < A.y: z < A.z;
}
bool operator ==(const p& A) const{
return x == A.x&&y == A.y&&z == A.z;
}
};
bool yzx(p A, p B){//y z x
if(A.y != B.y) return A.y < B.y;
return A.z != B.z? A.z < B.z : A.x < B.x;
}
bool cmpn(p A, p B){//n
return A.n < B.n;
}
p pp[maxn]; int c[maxn], Maxn;
int lowbit(int x){ return x&-x;}
int add(int x, int d){
for(int i = x; i <= Maxn; i += lowbit(i))
c[i] += d;
}
int sum(int x){
int ret = ;
for(int i = x; i; i -= lowbit(i))
ret += c[i];
return ret;
} int ans[maxn]; void cdq(int l, int r){
if(l == r) return ;
int m = (l+r)/;
cdq(l, m);
cdq(m+, r);
sort(pp+l, pp+r+, yzx);
for(int i = l; i <= r; i++)
if(pp[i].x <= m)
add(pp[i].z, );
else
ans[ pp[i].n ] += sum(pp[i].z);
for(int i = l; i <= r; i++)
if(pp[i].x <= m)
add(pp[i].z, -);
} int same[maxn];// smae[i] 表示 下标为i的ans 与 下标为same[i]相同 int main(){
int T; scanf("%d", &T);
while(T--){
int n;scanf("%d", &n);
for(int i = ; i < n ; i++){
pp[i].n = i;
scanf("%d%d%d", &pp[i].x, &pp[i].y, &pp[i].z);
Maxn = max(pp[i].z, Maxn);
}
sort(pp, pp+n);//x y z for(int i = ; i < n; ){
int j = i+;
while(j < n&&pp[i] == pp[j]) j++;
while(i < j)
same[ pp[i++].n ] = pp[j-].n;
}
for(int i = ; i < n; i++)
pp[i].x = i; memset(ans, , sizeof(int)*(n+) );
cdq(, n-); sort(pp, pp+n, cmpn);
for(int i = ; i < n; i++)
printf("%d\n", ans[ same[ pp[i].n ] ]);
}
return ; }
初学CDQ分治-NEU1702的更多相关文章
- 初学cdq分治学习笔记(可能有第二次的学习笔记)
前言骚话 本人蒟蒻,一开始看到模板题就非常的懵逼,链接,学到后面就越来越清楚了. 吐槽,cdq,超短裙分治....(尴尬) 正片开始 思想 和普通的分治,还是分而治之,但是有一点不一样的是一般的分治在 ...
- ACdream1157 Segments(CDQ分治 + 线段树)
题目这么说的: 进行如下3种类型操作:1)D L R(1 <= L <= R <= 1000000000) 增加一条线段[L,R]2)C i (1-base) 删除第i条增加的线段, ...
- 「分治」-cdq分治
cdq分治是一种分治算法: 一种分治思想,必须离线,可以用来处理序列上的问题(比如偏序问题),还可以优化1D/1D类型的DP.• 算法的大体思路我们可以用点对来描述.假定我们有一个长度为n的序列,要处 ...
- CDQ分治&整体二分学习个人小结
目录 小结 CDQ分治 二维LIS 第一道裸题 bzoj1176 Mokia bzoj3262 陌上花开 bzoj 1790 矩形藏宝地 hdu5126四维偏序 P3157 [CQOI2011]动态逆 ...
- 【教程】简易CDQ分治教程&学习笔记
前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦! CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...
- BZOJ 2683 简单题 ——CDQ分治
[题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...
- HDU5618 & CDQ分治
Description: 三维数点 Solution: 第一道cdq分治...感觉还是很显然的虽然题目不能再傻逼了... Code: /*=============================== ...
- 初识CDQ分治
[BZOJ 1176:单点修改,查询子矩阵和]: 1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 200 ...
- HDU5322 Hope(DP + CDQ分治 + NTT)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5322 Description Hope is a good thing, which can ...
随机推荐
- CGRectGet系列
CGRectGetHeight返回label本身的高度 CGRectGetMinY返回label顶部的坐标 CGRectGetMaxY 返回label底部的坐标 CGRectGetMinX 返回lab ...
- HDU 2767:Proving Equivalences(强连通)
http://acm.hdu.edu.cn/showproblem.php?pid=2767 题意:给出n个点m条边,问在m条边的基础上,最小再添加多少条边可以让图变成强连通.思路:强连通分量缩点后找 ...
- mongo 日记
分组代码片段 命令行代码: aggregate({$group:{_id:{A:'$A',B:'$B',C:'$C'}}}) 拿出唯一号有重复的数据: > db.aaaa.aggregate([ ...
- android FragmentPagerAdapter getItem方法没有执行
转自 http://blog.csdn.net/getchance/article/details/40263505 在一个 Android 应用中,我使用 FragmentPagerAdapter ...
- HDU 4712:Hamming Distance
Hamming Distance Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- php之上传类
<?php /** * Created by PhpStorm. * User: Administrator * Date: 2016/5/26 * Time: 20:29 */ class u ...
- Dirichlet's Theorem on Arithmetic Progressions 分类: POJ 2015-06-12 21:07 7人阅读 评论(0) 收藏
Dirichlet's Theorem on Arithmetic Progressions Time Limit: 1000MS Memory Limit: 65536K Total Submi ...
- Mybatis 和 Spring配置
一.使用的jar包就不详细讲解了,下载了Mybatis 和 Spring 的jar包基本上都添加上去了. 一图概括:(这是我使用的ar包,有些不是Mybatis 和 Spring 的 ) 二. web ...
- 2016年7月2日 星期六 --出埃及记 Exodus 14:29
2016年7月2日 星期六 --出埃及记 Exodus 14:29 But the Israelites went through the sea on dry ground, with a wall ...
- JAVAWeb使用POI做导出Excel
一.需要了解的API ①HSSFWorkBook //代表一个Excel文件 ②HSSFSheet //代表一个表 ③HSSFRow //代表一个表中的某一行 ④HSSFCell //代表一个表中的某 ...