[BZOJ 3262]陌上开花
今天写了到偏序问题,发现博主真的是个傻X
以前的写法
/**************************************************************
Problem: 3262
User: MiEcoku
Language: C++
Result: Accepted
Time:3416 ms
Memory:6296 kb
****************************************************************/
#include <cstdio>
#include <algorithm>
using namespace std;
#define mid ( l + r >> 1)
#define lowbit(x) ( x & -x)
struct GG {
int x, y, z, id, w;
void get () {
scanf("%d%d%d", &x, &y, &z);
}
}a[], b[];
], k;
; ; x -= lowbit(x)) ans += dis[x]; return ans; }
void add(int x, int y) { for ( ; x <= k; x += lowbit(x)) dis[x] += y; }
bool cmp1(GG a, GG b) { return a.x < b.x || (a.x == b.x && a.y < b.y) || (a.x == b.x && a.y == b.y && a.z < b.z); }
bool cmp2(GG a, GG b) { return a.y < b.y || (a.y == b.y && a.z < b.z); }
];
void cdq(int l, int r) {
, r);
sort(b+l, b+mid+, cmp2); sort(b+mid+, b+r+, cmp2);
;
for ( int i = l; i <= mid; i ++) {
while( b[q].y < b[i].y && q <= r) ans[b[q].id] += query(b[q].z), q ++;
add(b[i].z, b[i].w);
}
while( q <= r) ans[b[q].id] += query(b[q].z), q ++;
for ( int i = l; i <= mid; i ++) add(b[i].z, -b[i].w);
}
];
int main() {
scanf("%d%d", &_, &k);
; i <= _; i ++) a[i].get();
sort( a+, a++_, cmp1);
; i <= _; i ++) {
cnt ++;
].x || a[i].y != a[i+].y || a[i].z != a[i+].z)
b[++ n] = a[i], b[n].w = cnt, cnt = , b[n].id = n;
}
cdq(, n);
; i <= n; i ++)
d[ans[b[i].id]+b[i].w-] += b[i].w;
; i < _; i ++) printf("%d\n", d[i]);
}
可以看出这是个n * logn^2 的算法,这也是博主在大多数地方看到的写法,结果傻叉的以为cdq就是n * long n ^ 2 的算法
实际上可不可以更快?
void cdq(int l, int r) {
, r);
sort(b+l, b+mid+, cmp2); sort(b+mid+, b+r+, cmp2);
;
for ( int i = l; i <= mid; i ++) {
while( b[q].y < b[i].y && q <= r) ans[b[q].id] += query(b[q].z), q ++;
add(b[i].z, b[i].w);
}
while( q <= r) ans[b[q].id] += query(b[q].z), q ++;
for ( int i = l; i <= mid; i ++) add(b[i].z, -b[i].w);
}
可以看出,在cdq内部排了个序,然而真的有这个必要吗? 答案是否定的
我们都知道归并排序,可以看出,内部这个排序无非是想要将第二位排序
但在内部这个循环内就已经排序,所以那个排序可以省略
我们新开个数组
void cdq(int l, int r) {
, r);
, cnt = ;
for ( int i = l; i <= mid; i ++) {
while( b[q].y < b[i].y && q <= r) ans[b[q].id] += query(b[q].z), T[++ cnt] = b[q], q ++;
add(b[i].z, b[i].w); T[++ cnt] = b[i];
}
while( q <= r) ans[b[q].id] += query(b[q].z), T[++ cnt] = b[q], q ++;
for ( int i = l; i <= mid; i ++) add(b[i].z, -b[i].w);
cnt = ;
for ( int i = l; i <= r; ++ i) b[i] = T[++ cnt];
}
这样,我们就省略了内部的一个排序问题,做到n * long n
还能再快不?
能!
for ( int i = l; i <= mid; i ++) add(b[i].z, -b[i].w);
对于这句话,我们能不能将它优化掉?
我们考虑加入一个时间戳 tim
int query(int x, int K) {
;
; x -= lowbit(x)) if( mark[x] == K) ans += dis[x];
return ans;
}
void add(int x, int y, int K) {
for ( ; x <= k; x += lowbit(x)) if( mark[x] == K) dis[x] += y;
else mark[x] = K, dis[x] = y;
}
然后对树状数组进行点修改
这样我们就将常数再次优化了下
上总代码
/**************************************************************
Problem: 3262
User: MiEcoku
Language: C++
Result: Accepted
Time:1428 ms
Memory:9028 kb
****************************************************************/
/**************************************************************
Problem: 3262
User: MiEcoku
Language: C++
Result: Accepted
Time:3416 ms
Memory:6296 kb
****************************************************************/
#include <cstdio>
#include <algorithm>
using namespace std;
#define mid ( l + r >> 1)
#define lowbit(x) ( x & -x)
struct GG {
int x, y, z, id, w;
void get () {
scanf("%d%d%d", &x, &y, &z);
}
}a[], b[], T[];
], k, tim, mark[];
int query(int x, int K) {
;
; x -= lowbit(x)) if( mark[x] == K) ans += dis[x];
return ans;
}
void add(int x, int y, int K) {
for ( ; x <= k; x += lowbit(x)) if( mark[x] == K) dis[x] += y;
else mark[x] = K, dis[x] = y;
}
bool cmp1(GG a, GG b) { return a.x < b.x || (a.x == b.x && a.y < b.y) || (a.x == b.x && a.y == b.y && a.z < b.z); }
bool cmp2(GG a, GG b) { return a.y < b.y || (a.y == b.y && a.z < b.z); }
];
void cdq(int l, int r) {
, r);
, cnt = ; ++ tim;
for ( int i = l; i <= mid; i ++) {
while( b[q].y < b[i].y && q <= r) ans[b[q].id] += query(b[q].z, tim), T[++ cnt] = b[q], q ++;
add(b[i].z, b[i].w, tim); T[++ cnt] = b[i];
}
while( q <= r) ans[b[q].id] += query(b[q].z, tim), T[++ cnt] = b[q], q ++;
cnt = ;
for ( int i = l; i <= r; ++ i) b[i] = T[++ cnt];
}
];
int main() {
scanf("%d%d", &_, &k);
; i <= _; i ++) a[i].get();
sort( a+, a++_, cmp1);
; i <= _; i ++) {
cnt ++;
].x || a[i].y != a[i+].y || a[i].z != a[i+].z)
b[++ n] = a[i], b[n].w = cnt, cnt = , b[n].id = n;
}
cdq(, n);
; i <= n; i ++)
d[ans[b[i].id]+b[i].w-] += b[i].w;
; i < _; i ++) printf("%d\n", d[i]);
}
博主因为傻逼不知道这么写然后考试写的KT-tree被卡了

[BZOJ 3262]陌上开花的更多相关文章
- bzoj 3262 陌上花开 - CDQ分治 - 树状数组
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- BZOJ.3262.陌上花开([模板]CDQ分治 三维偏序)
题目链接 BZOJ3262 洛谷P3810 /* 5904kb 872ms 对于相邻x,y,z相同的元素要进行去重,并记录次数算入贡献(它们之间产生的答案是一样的,但不去重会..) */ #inclu ...
- Luogu 3810 & BZOJ 3262 陌上花开/三维偏序 | CDQ分治
Luogu 3810 & BZOJ 3263 陌上花开/三维偏序 | CDQ分治 题面 \(n\)个元素,每个元素有三个值:\(a_i\), \(b_i\) 和 \(c_i\).定义一个元素的 ...
- 【BZOJ 3262】 3262: 陌上花开 (CDQ分治)
3262: 陌上花开 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A ...
- BZOJ 3262 陌上花开 ——CDQ分治
[题目分析] 多维问题,我们可以按照其中一维排序,然后把这一维抽象的改为时间. 然后剩下两维,就像简单题那样,排序一维,树状数组一维,按照时间分治即可. 挺有套路的一种算法. 时间的抽象很巧妙. 同种 ...
- bzoj 3262 陌上花开
本质是一个三维偏序,一位排序后cdq分治,一维在子函数里排序,一维用树状数组维护. 把三维相等的合并到一个里面. #include<iostream> #include<cstdio ...
- BZOJ 3262 陌上花开 CDQ分治
= =原来复杂度还是nlog^2(n) Orz 被喷了 #include<cstdio> #include<cstdlib> #include<algorithm> ...
- BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- 【刷题】BZOJ 3262 [HNOI2008]GT考试
Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字. 他的不吉利数学A1A2...Am(0< ...
随机推荐
- 用java和汇编开发一个hello world系统内核
- U14.04 teamviewer install
转载http://www.cnblogs.com/kunyuanjushi/p/5205639.html 安装i386库 sudo apt-get install libc6:i386 libgcc1 ...
- Sqlserver中的几把锁和.net中的事务级别
当数据表被事务锁定后,我们再进行select查询时,需要为with(锁选项)来查询信息,如果不加,select将会被阻塞,直到锁被释放,下面介绍几种SQL的锁选项 SQL的几把锁 NOLOCK(不加锁 ...
- IDEA+DevTools实现热部署功能
开发IDE: Intellij IDEA 2018.1 SpringBoot:1.5.9.RELEASE 热部署 大家都知道在项目开发过程中,常常会改动页面数据或者修改数据结构,为了显示改动效果, ...
- IIS 身份验证
IIS 支持以下身份验证模式: 匿名.如果不需要对客户端进行身份验证(或者使用自定义身份验证机制,如窗体身份验证),则可将 IIS 配置为允许匿名访问.在该事件中,IIS 创建一个 Windows 令 ...
- 第08章-使用Spring Web Flow
使用Spring Web Flow Spring Web Flow是Spring MVC的扩展,它支持开发基于流程的应用程序.它将流程的定义与实现流程行为的类和视图分离开来. 1 在Spring中配置 ...
- 编写高质量代码改善C#程序的157个建议——建议34:为泛型参数设定约束
建议34:为泛型参数设定约束 “约束”这个词可能会引起歧义,有些人肯能认为对泛型参数设定约束是限制参数的使用,实际情况正好相反.没有“约束”的泛型参数作用很有限,倒是“约束”让泛型参数具有了更多的行为 ...
- 福大软工1816|K班—alpha冲刺
Part.1 开篇 队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Part.2 成员汇报 组员1(组长)柯奇豪 过去两天完成了哪些任务 了解前端方面的相关内容,便于后续对进 ...
- vba实现excel多表合并
Excel多表合并之vba实现 需求 保留列名,复制每一个excel里的数据,合并到一个excel 操作步骤 将要合并的文件放在同一文件夹下,复制过来就好(ps:最好不要直接操作原数据文件,避免操作失 ...
- CString::MakeLower Crash
记录一下使用CString::MakeLower可能导致的crash的一个问题: 问题重现: int _tmain(int argc, _TCHAR* argv[]){ std::string sT ...