CDQ分治 陌上花开(三维偏序)
CDQ分治或树套树可以切掉
CDQ框架:
- 先分
- 计算左边对右边的贡献
- 再和
所以这个题可以一维排序,二维CDQ,三维树状数组统计
CDQ代码
# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <algorithm>
# include <string.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
IL ll Read(){
RG char c = getchar(); RG ll x = 0, z = 1;
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
return x * z;
}
const int MAXN(100010), MAXK(200010);
int n, k, t[MAXK], m;
struct Point{
int a, b, c, cnt, id, ans;
IL bool operator ==(RG Point B) const{ return a == B.a && b == B.b && c == B.c; }
} p[MAXN], q[MAXN];
IL bool Cmp1(RG Point x, RG Point y){ return x.a < y.a || (x.a == y.a && (x.b < y.b || (x.b == y.b && x.c < y.c))); }
IL bool Cmp2(RG Point x, RG Point y){ return x.b < y.b || (x.b == y.b && (x.c < y.c || (x.c == y.c && x.a < y.a))); }
IL void Add(RG int x, RG int d){ for(; x <= k; x += x & -x) t[x] += d; }
IL int Query(RG int x){ RG int cnt = 0; for(; x; x -= x & -x) cnt += t[x]; return cnt; }
IL void CDQ(RG int l, RG int r){
if(l == r) return;
RG int mid = (l + r) >> 1; CDQ(l, mid); CDQ(mid + 1, r);
sort(p + l, p + r + 1, Cmp2);//可以归并排序
for(RG int i = l; i <= r; i++)
if(p[i].id <= mid) Add(p[i].c, p[i].cnt);
else p[i].ans += Query(p[i].c);
for(RG int i = l; i <= r; i++)
if(p[i].id <= mid) Add(p[i].c, -p[i].cnt);
}
int main(RG int argc, RG char* argv[]){
n = Read(); k = Read();
for(RG int i = 1; i <= n; i++) q[i] = (Point){Read(), Read(), Read()};
sort(q + 1, q + n + 1, Cmp1);
for(RG int i = 1; i <= n; i++)
if(q[i] == p[m]) p[m].cnt++;
else p[++m] = q[i], p[m].cnt = 1, p[m].id = m;
CDQ(1, m);
sort(p + 1, p + m + 1, Cmp1);
for(RG int i = 1; i <= m; i++) t[p[i].ans + p[i].cnt - 1] += p[i].cnt;
for(RG int i = 0; i < n; i++) printf("%d\n", t[i]);
return 0;
}
附上树套树
# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <string.h>
# include <algorithm>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
IL ll Read(){
RG char c = getchar(); RG ll x = 0, z = 1;
for(; c > '9' || c < '0'; c = getchar()) z = c == '-' ? -1 : 1;;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
return x * z;
}
const int MAXN(100010);
int n, k, ans[MAXN], NOW;
struct YYB{
int a, b, c;
IL bool operator <(RG YYB B) const{
if(a != B.a) return a < B.a;
if(b != B.b) return b < B.b;
return c < B.c;
}
IL bool operator ==(RG YYB B) const{
return a == B.a && b == B.b && c == B.c;
}
} yyb[MAXN];
struct SBT{
SBT *ch[2], *fa;
int size, val, cnt;
IL SBT(RG SBT *f, RG int v, RG int d){ cnt = size = d; val = v; fa = f; }
} *rt[MAXN << 1];
IL int Son(RG SBT *x){ return x -> fa -> ch[1] == x; }
IL int Size(RG SBT *x){ return x == NULL ? 0 : x -> size; }
IL void Updata(RG SBT *x){ x -> size = Size(x -> ch[0]) + Size(x -> ch[1]) + x -> cnt; }
IL void Rot(RG SBT *x){
RG int c = !Son(x); RG SBT *y = x -> fa;
y -> ch[!c] = x -> ch[c];
if(x -> ch[c] != NULL) x -> ch[c] -> fa = y;
x -> fa = y -> fa;
if(y -> fa != NULL) y -> fa -> ch[Son(y)] = x;
x -> ch[c] = y; y -> fa = x;
Updata(y);
}
IL void Splay(RG SBT *x, RG SBT *f){
while(x -> fa != f){
RG SBT *y = x -> fa;
if(y -> fa != f)
Son(x) ^ Son(y) ? Rot(x) : Rot(y);
Rot(x);
}
Updata(x); rt[NOW] = x;
}
IL void Insert(RG SBT *x, RG int v, RG int d){
if(rt[NOW] == NULL){ rt[NOW] = new SBT(NULL, v, d); return; }
while(2333){
RG int id = v > x -> val;
if(v == x -> val){ x -> size += d; x -> cnt += d; break; }
if(x -> ch[id] == NULL){
x -> ch[id] = new SBT(x, v, d);
x = x -> ch[id];
break;
}
x = x -> ch[id];
}
Splay(x, NULL);
}
IL int Calc(RG SBT *x, RG int v){
RG int cnt = 0;
while(x != NULL){
if(v >= x -> val) cnt += Size(x -> ch[0]) + x -> cnt;
if(v == x -> val) break;
x = x -> ch[v > x -> val];
}
return cnt;
}
IL void Modify(RG int id, RG int d){
for(NOW = yyb[id].b; NOW <= k; NOW += NOW & -NOW) Insert(rt[NOW], yyb[id].c, d);
}
IL int Query(RG int id){
RG int cnt = 0;
for(RG int i = yyb[id].b; i; i -= i & -i) cnt += Calc(rt[i], yyb[id].c);
return cnt;
}
int main(){
n = Read(); k = Read();
for(RG int i = 1; i <= n; i++)
yyb[i] = (YYB){Read(), Read(), Read()};
sort(yyb + 1, yyb + n + 1);
for(RG int i = 1, sum = 0; i <= n; i++){
sum++;
if(yyb[i] == yyb[i + 1]) continue;
ans[Query(i) + sum - 1] += sum;
Modify(i, sum);
sum = 0;
}
for(RG int i = 0; i < n; i++) printf("%d\n", ans[i]);
return 0;
}
CDQ分治 陌上花开(三维偏序)的更多相关文章
- 并不对劲的cdq分治解三维偏序
为了反驳隔壁很对劲的太刀流,并不对劲的片手流决定与之针锋相对,先一步发表cdq分治解三维偏序. 很对劲的太刀流在这里-> 参照一.二维偏序的方法,会发现一位偏序就是直接排序,可以看成通过排序使 ...
- cdq分治解决三维偏序
问题背景 在三维坐标系中有n个点,坐标为(xi,yi,zi). 定义一个点A比一个点B小,当且仅当xA<=xB,yA<=yB,zA<=zB.问对于每个点,有多少个点比它小.(n< ...
- 【算法学习】【洛谷】cdq分治 & P3810 三维偏序
cdq是何许人也?请参看这篇:https://wenku.baidu.com/view/3b913556fd0a79563d1e7245.html. 在这篇论文中,cdq提出了对修改/询问型问题(Mo ...
- hdu5618(cdq分治求三维偏序)
题意:给n(n<=100000)个点,坐标为(xi,yi,zi)(1<=xi,yi,zi<=100000),定义一个点A比一个点B小,当且仅当xA<=xB,yA<=yB, ...
- BZOJ 3262: 陌上花开 (cdq分治,三维偏序)
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; c ...
- SPOJ:Another Longest Increasing Subsequence Problem(CDQ分治求三维偏序)
Given a sequence of N pairs of integers, find the length of the longest increasing subsequence of it ...
- Luogu 3810 & BZOJ 3262 陌上花开/三维偏序 | CDQ分治
Luogu 3810 & BZOJ 3263 陌上花开/三维偏序 | CDQ分治 题面 \(n\)个元素,每个元素有三个值:\(a_i\), \(b_i\) 和 \(c_i\).定义一个元素的 ...
- CDQ分治-陌上花开(附典型错误及原因)
CDQ分治-陌上花开 题目大意 对于给遗传给定的序列: \[ (x,y,z)_1, (x,y,z)_2, (x,y,z)_3, \cdots, (x,y,z)_n \] 求: \[ \sum_{x_i ...
- HDU4742 CDQ分治,三维LIS
HDU4742 CDQ分治,三维LIS 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4742 题意: 每个球都有三个属性值x,y,z,要求最长的lis的 ...
- BZOJ3262 陌上花开 —— 三维偏序 CDQ分治
题目链接:https://vjudge.net/problem/HYSBZ-3262 3262: 陌上花开 Time Limit: 20 Sec Memory Limit: 256 MBSubmit ...
随机推荐
- JSON工具类
import java.sql.Timestamp; import java.util.Collection; import java.util.Date; import org.soul.util. ...
- 设置修改CentOS系统时区
一.时区 1. 查看当前时区date -R 2. 修改设置时区方法(1)tzselect方法(2) 仅限于RedHat Linux 和 CentOS系统timeconfig方法(3) 适用于Debia ...
- Python面向对象篇(3)-封装、多态、反射及描述符
1. 多态 多态,最浅显的意识就是同一事物具有多种形态,这很好理解,动物是一个大类,猫类属于动物类,狗类属于动物类,人也是属于动物类,那能理解成,猫.狗.人是一样的吗?当然不是,还有,水,分为液体.固 ...
- PHP实现水印效果(文字、图片)
第一种 <?php /** * 功能:给一张图片加上水印效果 * $i 要加水印效果的图片 * $t 水印文字 * $size 文字大小 * $pos 水印的位置 * $color 文字的颜色 ...
- .net Winfrom 僵尸窗口 的问题
执行顺序如下: Form1 form1 =new Form1(); form1.ShowDialog(); Form2 form2= Application.OpenForms["Form2 ...
- deplyed使用归纳(转自月下独奏)
deployd:一个生成后端数据的软件,简单的说就是大部分的前端不会后端,即使会也很难在深入到数据库进行设置一些前端所需数据的创建与查询的后端程序的书写,所以此时就是deployd大显身手的时候了. ...
- iOS.Animations.by.Tutorials.v2.0汉化(三)
第2章:Springs 在前一章中,您学习了如何创建UIKit的基本动画,包括如何提供起始值和结束值随着时间的UIKit,自动为你创建一个动画. 到目前为止,你的动画一直是单方向的流体运动.当你激活一 ...
- linux 安全基本防护 用户提权 ssh访问控制
linu安全应用 信息安全分类: 物理安全:主机/机房环境 系统安全:操作系统 应用安全:各种网络服务,应用程序 网络安全:网络访问控制,防火墙规则 数据安全:信息的备份与恢复,加密解密 管理安全:保 ...
- Bind、Apply、Call三者的区别
1)bind与apply.call 的最大区别就是:bind不会立即调用,其他两个会立即调用 var fn = { _int: function(){return 3}, fun: function( ...
- 问题解决了,可是为什么呢?could not find the main class.program will exitmain
今天重新学习socket编写简单的在线聊天,简单功能实现的情况下,一时心血来潮便想要把这程序打成可执行的jar包,以便于在桌面直接双击运行. 参照自己之前写的那篇<>打好两个jar包以后却 ...