HDU5324 cqd分治
HDU5324 cqd分治
标签(空格分隔): 未分类
给你两个长度相同数列,求第一个不上升,第二个不下降的最长子序列长度。
这里要求的子序列对第一个和第二个来说是相同的。即如果你在第一个序列里选了第i个,那么在第二个序列里也要选第i个。
首先我们考虑怎么解决只有一个序列的情况。
这就是最普通的最长不下降子序列。考虑\(O(nlogn)\)的做法。
首先仍然是DP,$f[i]=\max(f[j]+1) , j < i $ & $ a_j < a_i \(. 我们需要考虑怎么在\)logn\(时间内求出\)\max(f[j]+1)$.这很容易。对于i,我们建立一颗权值线段树,每次单点修改,求区间最大值即可。(可以用zkw)
那么我们考虑如何解决这个二维问题。首先DP方程还是这样。
\[f[i]=\max(f[j]+1) , j < i , a_j > a_i , b_j<b_i \]
问题在于如果我们想用\(log\)的复杂度维护这个\(\max(f[j]+1)\),我们就需要一个二维线段树,这是非常令人难过的。因为首先二维线段树不好写不好调,而且更关键的是很容易MLE(或者TLE?)。
那么这类二维数据结构问题都可以考虑使用cdq分治。
cdq分治的基本思想就是把所有询问离线统一计算,这样我们就可以在计算的时候进行分治。
其实多数情况下就是把所有位置上的答案都计算出来。
所以cqd分治的第一个条件就是允许离线。
以这道题为例,我们考虑计算所有的\(f[i]\).如果用\(gao(1,n)\)表示计算\(f[1]\)~\(f[n]\),那么\(gao(1,n)\)就可以分成\(gao(1,n/2) , gao(n/2+1,n)\),这样我们就可以分治了。
当然直接分治是不对的,因为一个\(f[i]\)是受到他之前所有的\(f[j]\)的影响的。这在\(gao(1,n/2)\)时没有问题,但是在\(gao(n/2+1)\)时就会少考虑前一半对这一半的贡献。
那么很好办,cqd分治和普通分治的主要区别就是我们可以在\(gao(1,n/2)\)之后用\(O(n)或者O(nlogn)\)时间把前一半已经计算出来的\(f\)值对后一半的影响加进去。这样总体复杂度就是\(O(nlogn)\)或者\(O(nlog^2n)\)。具体复杂度取决于合并时的复杂度。
注意这里有cdq分治成立的第二个条件,那就是前一半对后一半的贡献是可以独立计算的,而且后一半不会影响前一半。否则没办法合并。
对于这道题而言,我们\(gao(1,n)\)的时候,先计算前一半,然后把前一半和后一半的数分别排序,对于后一半每个数,把前一半里比它小的插入线段树中,然后查询权值线段树中的最大值即可。合并复杂度\(O(nlogn)\),总体复杂度\(O(nlog^2n)\),和二维线段树一样,但是好写多了。
另外这道题要求答案字典序最小,那么DP的时候倒序做就可以了。(想一想就懂了)
实际上cdq分治就是在一个维度上改变了求解问题的顺序,从而避免了对整体使用二维数据结构。
HDU5324 cqd分治的更多相关文章
- [Hdu1166]敌兵布阵(CQD分治)
CQQ分治 Code #include <cstdio> #include <cstring> #define N 50010 struct info{ int x,p,v; ...
- CQD(陈丹琦)分治 & 整体二分——专题小结
整体二分和CDQ分治 有一些问题很多时间都坑在斜率和凸壳上了么--感觉斜率和凸壳各种搞不懂-- 整体二分 整体二分的资料好像不是很多,我在网上找到了一篇不错的资料: 整体二分是个很神的东西 ...
- HDU5730 Shell Necklace(DP + CDQ分治 + FFT)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5730 Description Perhaps the sea‘s definition of ...
- bzoj3110: [Zjoi2013]K大数查询 【cdq分治&树套树】
模板题,折腾了许久. cqd分治整体二分,感觉像是把询问分到答案上. #include <bits/stdc++.h> #define rep(i, a, b) for (int i = ...
- 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 ...
- maomao的每日动向
\(2019.02.04\) \(Nothing\) \(to\) \(do\). \(2019.02.05\) - 早上睡到\(12\)点 - 中午下午:吃饭串门拜年 - 晚上:吹爆<流浪地球 ...
- P4027 [NOI2007]货币兑换
传送门 首先有一个显然的贪心,每次操作都要做到底,为了最优不会出现只卖一部分或者只买一部分的操作 所以设 $f[i]$ 表示前 $i$ 天得到的最大价值,那么对于每一个 $i$,枚举所有 $j< ...
- [2015hdu多校联赛补题]hdu5324 Boring Class
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5324 题意:给你一个二维的序列,让你找出最长的第一维升第二维降的子序列(如果多个答案,输出字典序最小) ...
- 浅谈CDQ分治与偏序问题
初识CDQ分治 CDQ分治是一个好东西,一直听着dalao们说所以就去学了下. CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. ...
随机推荐
- Linux系统内核参数优化
Linux服务器内核参数优化 cat >> /etc/sysctl.conf << EOF # kernel optimization net.ipv4.tcp_fin_tim ...
- 如何使用 libtorch 实现 AlexNet 网络?
如何使用 libtorch 实现 AlexNet 网络? 按照图片上流程写即可.输入的图片大小必须 227x227 3 通道彩色图片 // Define a new Module. struct Ne ...
- shell 从文件中读取批量文件名并做命令行操作
222文件内容: /home/zhangsuosheng/Desktop/9-30/9_30/1bak/1538291162.png /home/zhangsuosheng/Desktop/9-30/ ...
- windows 最大支持线程数
WINDOWS操作系统中可以允许最大的线程数 默认情况下,一个线程的栈要预留1M的内存空间 而一个进程中可用的内存空间只有2G,所以理论上一个进程中最多可以开2048个线程 但是内存当然不可能完全拿来 ...
- 使用maven为web工程引入jstl包时报错了
原pom文件: <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</a ...
- sap 动态字段的使用
1.sap中的动态字段其实类似c#里面的指针,都是指向的地址. 只是写法不同,sap 中的field-symbols就是类似指针. , b TYPE i. FIELD-SYMBOLS <fs&g ...
- PATH and CLASSPATH
PATH and CLASSPATH 1. 可以不设置PATH直接运行Java应用的.PATH的设置只是为了使用上的方便. 2. PATH设置的是Java的bin目录,使得bin目录下的可执行程序能够 ...
- python数据描述符
Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题苦恼的朋友提 ...
- Mac使用操作
快捷键退出程序:Command + Q 快捷键关闭窗口:Command + W(关闭程序的窗口不一定是退出程序) 单击左上角黑苹果,菜单里面有强制退出 Finder菜单的偏好设置,高级设置菜单里面可以 ...
- Restful风格API
一:协议 API与用户的通信协议,总是使用HTTPS协议. 二:域名 应该尽量将API部署在专用域名之下. https://api.example.com 如果确定API很简单,不会有进一步扩展,可以 ...