HDU4742 CDQ分治,三维LIS

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4742

题意:

每个球都有三个属性值x,y,z,要求最长的lis的长度和方案数

题解:

一维LIS很好求,dp一下就行

二维的LIS,将第一维排序后,和第一维一样

那么三维的lis怎么做了,我们很容易想到将第一维排序后分治的写,分了后, 按照y排序,怎么治呢?用树状数组更新前前x的最大值,然后再用dp更新即可

这里需要注意,和陌上花开等板子题不一样,我们这里不能分了左半部分后再直接分右半部分,这个地方卡了我好久。这里的分治运用是用来给dp服务的,我们dp是由前面的状态转移过来,所以,我们要先更新左半边后再去分治右半边

代码:

#include <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int mod = 1 << 30;
int n;
struct P {
int x, y, z, id;
} point[maxn], now[maxn];
struct A {
int max, sum;
} ans[maxn], tr[maxn];
bool cmpx(const P a, const P b) {
return a.x < b.x;
}
bool cmpy(const P a, const P b) {
return a.y < b.y;
}
bool cmpz(const P a, const P b) {
return a.z < b.z;
} int lowbit(int x) {
return (x & -x);
} void insert(int x, A tmp) {
for(int i = x; i <= n; i += lowbit(i)) {
if(tr[i].max == tmp.max) {
tr[i].sum += tmp.sum;
tr[i].sum %= mod;
} else if(tr[i].max < tmp.max) {
tr[i].sum = tmp.sum;
tr[i].max = tmp.max;
}
}
} A getsum(int x) {
A ret;
ret.max = -1;
for(int i = x; i >= 1; i -= lowbit(i)) {
if(tr[i].max > ret.max) {
ret.max = tr[i].max;
ret.sum = tr[i].sum;
} else if(tr[i].max == ret.max) {
ret.sum += tr[i].sum;
ret.sum %= mod;
}
}
return ret;
} void clear(int x) {
for(int i = x; i <= n; i += lowbit(i)) {
tr[i].max = 0;
tr[i].sum = 0;
}
} void solve(int l, int r) {
if(l == r) return ;
int mid = l + r >> 1;
solve(l, mid);
for(int i = mid + 1; i <= r; i++)
now[i] = point[i];
sort(point + l, point + mid + 1, cmpz);
sort(point + mid + 1, point + r + 1, cmpz);
for(int i = mid + 1, top = l; i <= r; i++) {
while(top <= mid && point[top].z <= point[i].z) {
insert(point[top].x, ans[point[top].id]);
top++;
}
A ret = getsum(point[i].x);
ret.max++;
if(ret.max == ans[point[i].id].max) {
ans[point[i].id].sum += ret.sum;
ans[point[i].id].sum %= mod;
} else if(ret.max > ans[point[i].id].max) {
ans[point[i].id] = ret;
}
}
for(int i = l; i <= mid; i++) clear(point[i].x);
for(int i = mid + 1; i <= r; i++)
point[i] = now[i]; solve(mid + 1, r);
}
//dp[i]=max(dp[i-1],dp[j]+1)
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d %d %d", &point[i].x, &point[i].y, &point[i].z);
point[i].id = i;
}
sort(point + 1, point + 1 + n, cmpx);
for(int i = 1, xx = point[1].x - 1, num = 0; i <= n; i++) {
if(point[i].x != xx) num++, xx = point[i].x;
point[i].x = num;
}
sort(point + 1, point + 1 + n, cmpy); for(int i = 1; i <= n; i++) {
ans[i].max = 1;
ans[i].sum = 1;
}
solve(1, n);
A ret;
ret.max = -1;
for(int i = 1; i <= n; i++) {
if(ret.max == ans[i].max) {
ret.sum += ans[i].sum;
ret.sum %= mod;
} else if(ret.max < ans[i].max) {
ret = ans[i];
}
}
printf("%d %d\n", ret.max, ret.sum);
}
return 0;
}

HDU4742 CDQ分治,三维LIS的更多相关文章

  1. BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...

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

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

  3. 【算法】CDQ分治 -- 三维偏序 & 动态逆序对

    初次接触CDQ分治,感觉真的挺厉害的.整体思路即分而治之,再用之前处理出来的答案统计之后的答案. 大概流程是(对于区间 l ~ r): 1.处理 l ~mid, mid + 1 ~ r 的答案: 2. ...

  4. NEUOJ 1702:撩妹全靠魅力值(CDQ分治三维偏序)

    http://acm.neu.edu.cn/hustoj/problem.php?id=1702 思路:三维偏序模板题,用CDQ分治+树状数组或者树套树.对于三元组(x,y,z),先对x进行排序,然后 ...

  5. cdq分治·三维偏序问题

    转载自FlashHu大佬的博客CDQ分治总结(CDQ,树状数组,归并排序),在讲述部分有部分删改,用了自己的代码 CDQ分治的思想 CDQ分治是基于时间的离线分治算法.这一类分治有一个重要的思想——用 ...

  6. CDQ分治 三维偏序

    这应该是一道CDQ分治的入门题目 我们知道,二维度的偏序问题直接通过,树状数组就可以实现了,但是三维如何实现呢? 我记得以前了解过一个小故事,应该就是分治的. 一个皇帝,想给部下分配任务,但是部下太多 ...

  7. BZOJ 2244: [SDOI2011]拦截导弹 (CDQ分治 三维偏序 DP)

    题意 略- 分析 就是求最长不上升子序列,坐标取一下反就是求最长不下降子序列,比较大小是二维(h,v)(h,v)(h,v)的比较.我们不看概率,先看第一问怎么求最长不降子序列.设f[i]f[i]f[i ...

  8. BZOJ.1935.[SHOI2007]Tree园丁的烦恼(CDQ分治 三维偏序)

    题目链接 矩形查询可以拆成四个点的前缀和查询(树套树显然 但是空间不够) 每个操作表示为(t,x,y),t默认有序,对x分治,y用树状数组维护 初始赋值需要靠修改操作实现. //119964kb 43 ...

  9. BZOJ.3262.陌上花开([模板]CDQ分治 三维偏序)

    题目链接 BZOJ3262 洛谷P3810 /* 5904kb 872ms 对于相邻x,y,z相同的元素要进行去重,并记录次数算入贡献(它们之间产生的答案是一样的,但不去重会..) */ #inclu ...

随机推荐

  1. bzoj1412 狼和羊的故事

    Description “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! O ...

  2. Inno setup 卸载时删除程序文件夹(文件)

    Inno setup 卸载时删除程序文件夹(文件) //删除所有配置文件以达到干净卸载的目的 procedure CurUninstallStepChanged(CurUninstallStep: T ...

  3. 【Leetcode链表】分隔链表(86)

    题目 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前. 你应当保留两个分区中每个节点的初始相对位置. 示例: 输入: head = 1->4 ...

  4. KiCad 5.1.0 镜像圆弧后错位问题

    KiCad 5.1.0 镜像圆弧后错位问题 看官方回复这个问题将在 5.1.3 进行修复,因为这段时间在举行 KiCon 活动. 看到这个问题并不是非常严重,不是致命的,所以已经从 5.1.0 跳到 ...

  5. Java练习 SDUT-4303_简单的复数运算(类和对象)

    简单的复数运算(类和对象) Time Limit: 2000 ms Memory Limit: 65536 KiB Problem Description 设计一个类Complex,用于封装对复数的下 ...

  6. python的str,unicode对象的encode和decode方法, Python中字符编码的总结和对比bytes和str

    python_2.x_unicode_to_str.py a = u"中文字符"; a.encode("GBK"); #打印: '\xd6\xd0\xce\xc ...

  7. 域名拆分 tld

    概念 URL Universal Resource Locator ,统一资源定位符. 用处:用来标识互联网资源的唯一地址. 本质:提供了互联网上任一资源地址的通用表示方法. protocol://h ...

  8. typeid, const_cast<Type>的使用

    #include <bits/stdc++.h> using namespace std; class A { public : void Show() { cout << & ...

  9. qt 中lineEdit->setText()输出double

    在qt中需要将获取到的double 值在ui界面上显示出来,便于观察.但是lineEdit控件的setText()要求的参数是string. 所以我们先要进行转化,将double 转化为string. ...

  10. 详解ThinkPHP支持的URL模式有四种普通模式、PATHINFO、REWRITE和兼容模式

    URL模式     URL_MODEL设置 普通模式    0 PATHINFO模式     1 REWRITE模式     2 兼容模式     3 如果你整个应用下面的模块都是采用统一的URL模式 ...