嘟嘟嘟




很显然我开始学\(CDQ\)分治了。

我刚开始学的时候看了一篇博客,上面全是一些抽象的概念,看完后真是一头雾水,最后还不得不抄了这题的代码。

但这样可不行呀……

于是我就不打算再扣那篇博客,而是自己想,最后真的自己想明白了。




(个人感觉这道题跟\(CDQ\)分治关系不大)

首先想一下二维偏序:我们先按第一维排序,然后第二维动态的用树状数组维护。也就是说,得保证前几维都有序的前提下,才可以用数据结构维护最后一维。

现在换到了三维:所以我们必须保证在前两维有序的前提下,才能维护第三维。

首先都能想到,按第一维排序,这样就保证第一维有序了。

如何保证第二维\(y\)有序?如果硬排序,又会导致第一维\(x\)乱序。但是排序还是要排的。有没有一种排序方法能使第一维“不太乱”呢?

答案是有的:归并排序!对于区间\([L, R]\),虽然\([L, mid]\)和\([mid + 1, R]\)中的\(y\)有序,\(x\)乱序,但是\([mid + 1, R]\)中的任何一个元素的\(x\)仍是比\([L, mid]\)中的任何一个都大的!因此右区间相对于左区间保证了前两维有序,所以此时我们就能用树状数组维护第三维了!

这大概就是\(CDQ\)分治中的左修改只会对右询问造成影响的意思吧。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e5 + 5;
const int maxm = 2e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
} int n, m, k;
struct Node
{
int x, y, z, cnt, sum;
bool operator < (const Node& oth)const
{
if (x != oth.x) return x < oth.x;
if (y != oth.y) return y < oth.y;
return z < oth.z;
}
bool operator != (const Node& oth)const
{
return x != oth.x || y != oth.y || z != oth.z;
}
bool operator > (const Node& oth)const
{
if(y != oth.y) return y < oth.y;
return z <= oth.z;
}
}a[maxn], t[maxn]; int c[maxm];
int lowbit(int x)
{
return x & -x;
}
void init(int pos)
{
for(; pos <= k; pos += lowbit(pos))
if(c[pos] != 0) c[pos] = 0;
else break;
}
void add(int pos, int d)
{
for(; pos <= k; pos += lowbit(pos)) c[pos] += d;
}
int query(int pos)
{
int ret = 0;
for(; pos; pos -= lowbit(pos)) ret += c[pos];
return ret;
} void cdqSolve(int L, int R)
{
if(L == R) return;
int mid = (L + R) >> 1, id1 = L, id2 = mid + 1;
cdqSolve(L, mid); cdqSolve(mid + 1, R);
for(int i = L; i <= R; ++i)
{
if(id2 > R || (id1 <= mid && a[id1] > a[id2])) //这个大于号是比较第二维的,不是真正的大于号
{
t[i] = a[id1++];
add(t[i].z, t[i].cnt);
}
else
{
t[i] = a[id2++];
t[i].sum += query(t[i].z);
}
}
for(int i = L; i <= R; ++i) a[i] = t[i], init(a[i].z);//分治的每一层,别忘了清空树状数组
} int ans[maxn]; int main()
{
m = read(); k = read();
for(int i = 1; i <= m; ++i) t[i].x = read(), t[i].y = read(), t[i].z = read();
sort(t + 1, t + m + 1);
for(int i = 2, j = 1; i <= m + 1; ++i)
if(t[j] != t[i] || i == m + 1) a[++n] = t[j], a[n].cnt = i - j, j = i;
cdqSolve(1, n);
for(int i = 1; i <= n; ++i) ans[a[i].sum + a[i].cnt - 1] += a[i].cnt;
for(int i = 0; i < m; ++i) write(ans[i]), enter;
return 0;
}

luogu【模板】三维偏序(陌上花开)的更多相关文章

  1. luogu P3810 三维偏序(陌上花开)cdq分治

    题目链接 思路 对一维排序后,使用$cdq$分治,以类似归并排序的方法处理的二维,对于满足$a[i].b \leq a[j].b$的点对,用树状数组维护$a[i].c$的数量.当遇到$a[i].b&g ...

  2. [Luogu 3810]三维偏序

    Description 有 $ n $ 个元素,第 $ i $ 个元素有 $ a_i $ .$ b_i $ .$ c_i $ 三个属性,设 $ f(i) $ 表示满足 $ a_j \leq a_i $ ...

  3. Luogu P3810 【模板】三维偏序(陌上花开)(CDQ分治)

    题目 以三维偏序为例来讲一下CDQ分治. CDQ的本质就是把一个序列分成两段,计算左边对右边的贡献,然后分治. 不过一般都是先分治到底再从下往上算,这样可以先归并再算. 比如这道题,我们先按第一维排序 ...

  4. P3810 【模板】三维偏序(陌上花开)

    P3810 [模板]三维偏序(陌上花开) cdq分治+树状数组 三维偏序模板题 前两维用cdq分治,第三维用树状数组进行维护 就像用树状数组搞逆序对那样做--->存权值的出现次数 attenti ...

  5. Luogu 3810 & BZOJ 3262 陌上花开/三维偏序 | CDQ分治

    Luogu 3810 & BZOJ 3263 陌上花开/三维偏序 | CDQ分治 题面 \(n\)个元素,每个元素有三个值:\(a_i\), \(b_i\) 和 \(c_i\).定义一个元素的 ...

  6. P3810 【模板】三维偏序(陌上花开)(CDQ分治)

    题目背景 这是一道模板题 可以使用bitset,CDQ分治,K-DTree等方式解决. 题目描述 有 nn 个元素,第 ii 个元素有 a_iai​.b_ibi​.c_ici​ 三个属性,设 f(i) ...

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

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

  8. P3810 -三维偏序(陌上花开)cdq-分治

    P3810 [模板]三维偏序(陌上花开) 思路 :按照 1维排序 二维 分治三维树状数组维护 #include<bits/stdc++.h> using namespace std; #d ...

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

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

  10. BZOJ3262 陌上花开 —— 三维偏序 CDQ分治

    题目链接:https://vjudge.net/problem/HYSBZ-3262 3262: 陌上花开 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit ...

随机推荐

  1. Java - HashMap值大于128问题

    class Solution { public boolean wordPattern(String pattern, String str) { HashMap<Character,Integ ...

  2. Bash:常用命令工具-tr命令

    tr命令可以用来做简单的字符替换与删除,常用的有-d, -s选项.它的替换与删除是按单个字符来的 假设有以下文本: Read from the file words.txt and output th ...

  3. 总结oninput、onchange与onpropertychange事件的使用方法和差别

    onchange事件仅仅在键盘或者鼠标操作改变对象属性,且失去焦点时触发,脚本触发无效:而onkeydown/onkeypress/onkeyup在处理复制.粘贴.拖拽.长按键(按住键盘不放)等细节上 ...

  4. PHP生成缩略图(1)--简单缩略图

    原理:就是将大图缩小并另存为小图 以此图为例,使其生成缩略图! 首先要使用到以下函数 imagecopyresampled() 重采样拷贝部分图像并调整大小 bool imagecopyresampl ...

  5. BZOJ4977: [[Lydsy1708月赛]跳伞求生

    传送门 直接贪心 考虑到 \(n\) 个人的贡献都是 \(a_i\),另外 \(m\) 个人的贡献都是 \(c_i-b_i\) 首先 \(a_i>b_j\) 的限制不好做,所以将 \(a,b\) ...

  6. JavsScript--on与addEventListener的使用与两者的不同

    Js之on和addEventListener的使用与不同 一.首先介绍两者的用法: 1.on的用法:以onclick为例 第一种: obj.onclick = function(){ //do som ...

  7. Atitit.resin  could not create the java virtual machine问题

    Atitit.resin  could not create the java virtual machine问题 1. 正常的参数是这样1 2. 错误的cmd运行时候的参数1 3. 输出2 4. 原 ...

  8. html单元格导出excel图形环境问题

     现象:报表页面端展现正常,点击导出excel,选择完是否分页后页面没有反应,后台润乾日志中错误信息: runqianReportLogger : [ERROR]  - Error: at com ...

  9. linux centos7最小化安装NAT模式网络设置

    1.网络连接设置为NAT模式2.开启CentOS7,以root登陆3.vi /etc/sysconfig/network-scripts/ifcfg-ensXXXX4.设置BOOTPROTO=dhcp ...

  10. maven属性、profile、资源过滤、不同环境构建项目

    maven针对不同环境构建项目 maven使用属性.profile及资源过滤支持针对不同环境构建项目 maven属性 maven共有六类属性 1.最常见的是自定义属性,即在pom文件里通过<pr ...