[HEOI2016/TJOI2016]序列 CDQ分治
题解:
首先我们观察一下,如果一个点对(j, i),
要符合题中要求要满足哪些条件?
首先我们设 j < i
那么有:
j < i
max[j] < v[i]
v[j] < min[i]
(注意下面两个式子都是用的v[i],v[j],,,而不是i , j。。。之前因为这个问题纠结了很久,其实我也不知道我在纠结什么。。。)
这三个式子是不是很眼熟?
如果式子变成:
j < i
max[j] < max[i]
min[j] < min[i]
是不是就和三维偏序一模一样了?
但是还是略有区别,不过区别不大,所以我们考虑一个变种的三维偏序。
在之前的板子中我用的是归并排序。
但由于这个题目式子不同。所以归并排序不在合适
首先CDQ可以保证id的相对有序。
而为了比较max[j] 和 v[i]
我们使用sort,分别对左边按max排序,对右边按id排序。
为了比较v[j] < min[i]
我们使用树状数组,
在满足max[j] < v[i]的条件下,
在树状数组的第v[j]位插入大小为ans[j]的数。
查询时用min[i]查询。
树状数组维护最大值(此时不满足区间减法)
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 100100
#define getchar() *o++
#define lowbit(x) (x & (-x))
#define D printf("line in %d\n", __LINE__);
char READ[], *o = READ;
/*变种三维偏序,
总的来说就是要保证这三个式子。
i < j
max[j] < v[i]
v[j] < min[i]
可以看出的三维偏序是非常类似的,
所以也可以用CDQ + 归并 + 树状数组实现。
CDQ维护下标,也就是第一个式子
归并维护第二个式子,
树状数组用于在归并的条件下查询满足第3个式子的贡献。
本质上是类似DP的东西?
p[i].ans 表示以i为结尾的子序列的最长长度
*/
/*初始状态下id相对有序,归并维护maxj的顺序
但是这个好像和原来的不一样???
原来的是维护maxj < maxi,两边都是一样的属性,
所以归并完就排好了,因为它的要求对于左边和右边而言是一样的,
都是要按maxj排序,这样的话归并一遍,等到回去的时候这个小块就是按maxj排好序的。
就符合上面的要求。
但是这个maxj < i,两边是不同的属性,所以不太适用。。。
因为这样的话要求小块处理完后左边是按照maxnj排序的,而右边却是按照i排序的。
因此这就不便于处理,也就是根本不能排。
而且这里左边对右边的贡献是有顺序限制的,因此小块处理也要分开
还是要用sort啊......*/
int n, m, ans, maxn;
int power[AC], tmp[AC], c[AC];
struct node{
int id, max, min, ans, v;
}p[AC]; inline int read()
{
int x = ; char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} inline void upmin(int &a, int b)
{
if(a > b) a = b;
} inline void upmax(int &a, int b)
{
if(b > a) a = b;
} inline bool cmp1(node a, node b)//按max排序
{
return a.max < b.max;
} inline bool cmp2(node a, node b)//v排序
{
return a.v < b.v;
}
//按id排序,因为右边块的调用是在处理完左边和左边对右边的贡献后的,
inline bool cmp3(node a, node b)//而这时右边已经不在是id有序的状态了,(因为按v排了序),但是又要求id有序,所以还要还原一次
{
return a.id < b.id;
} //min由树状数组负责
void pre()
{
int a, b;
n = read(), m = read();
for(R i = ; i <= n; i++)
{
p[i].id = i;
p[i].v = p[i].max = p[i].min = read();
}
for(R i = ; i <= m; i++)
{
a = read(), b = read();
upmax(p[a].max, b);
upmax(maxn, b);
upmin(p[a].min, b);
}
} inline void add(int x, int w)//维护前缀最大值的树状数组(不符合区间减法)
{
for(R i = x; i <= maxn; i += lowbit(i)) upmax(c[i], w);//维护最大值
}//因为维护的格子是以v[i]为基础的,存的东西是ans[i],所以上界自然是max(v[i]) inline int sum(int x)//查询前缀最大值
{
int ans = ;
for(R i = x; i ; i -= lowbit(i)) upmax(ans, c[i]);
return ans;
} inline void clear(int x)
{
for(R i = x; i <= maxn; i += lowbit(i)) c[i] = ;
} void CDQ(int l, int r)
{
if(l < r)
{
int mid = (l + r) >> ;
CDQ(l, mid);
sort(p + l, p + mid + , cmp1);//按max排序
sort(p + mid + , p + r + , cmp2);//按v排序
int i = l, j = mid + ;
while(j <= r)//因为要靠这个代替内层循环,所以这个要用||,但是又不能直接用||,因为会导致死循环(i一直不符合条件)
{//j一直往后走,因此直接判断j,相当于外层只是控制j的
while(p[i].max <= p[j].v && i <= mid) add(p[i].v, p[i].ans), ++i;
upmax(p[j].ans, sum(p[j].min) + ), ++j;//还要加上自己,因为i往后移动了,所以这个时候再判断大小就不对了,所以干脆强制转移
} //让外层循环代替内层循环
for(R k = l; k <= i; k++) clear(p[k].v);//error!!!放进去了多少就拿出来多少,不然就浪费了
sort(p + mid + , p + r + , cmp3);//还原id
CDQ(mid + , r);//因为这个要统计最长长度,是有先后顺序的,陌上花开是在统计个数,是可以允许没有顺序的
}
else upmax(p[l].ans, );//最少也是1了
} void work()
{
for(R i = ; i <= n; i++) upmax(ans, p[i].ans);
printf("%d\n", ans);
// printf("time used... %lf\n", (double)clock()/CLOCKS_PER_SEC);
} int main()
{
// freopen("in.in", "r", stdin);
fread(READ, , , stdin);
pre();
CDQ(, n);
work();
// fclose(stdin);
return ;
}
[HEOI2016/TJOI2016]序列 CDQ分治的更多相关文章
- 洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP
洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他. 玩具上有一个数列,数列中某些项的值可能会 ...
- 【洛谷P4093】 [HEOI2016/TJOI2016]序列 CDQ分治+动态规划
你发现只会改变一个位置,所以可以直接进行dp 具体转移的话用 CDQ 分治转移就好了~ #include <bits/stdc++.h> #define N 100006 #define ...
- BZOJ4553/洛谷P4093 [HEOI2016/TJOI2016]序列 动态规划 分治
原文链接http://www.cnblogs.com/zhouzhendong/p/8672434.html 题目传送门 - BZOJ4553 题目传送门 - 洛谷P4093 题解 设$Li$表示第$ ...
- cdq分治(hdu 5618 Jam's problem again[陌上花开]、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、[HEOI2016/TJOI2016]序列、[NOI2007]货币兑换 )
hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; ...
- 洛谷 P4093 [HEOI2016/TJOI2016]序列 解题报告
P4093 [HEOI2016/TJOI2016]序列 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一 ...
- 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组
[BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...
- [BZOJ4553][TJOI2016&&HEOI2016]序列(CDQ分治)
4553: [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1202 Solved: 554[Su ...
- [BZOJ4553][HEOI2016]序列 CDQ分治
4553: [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec Memory Limit: 128 MB Description 佳媛姐姐过生日的时候,她的小伙 ...
- 洛谷 P4093 [HEOI2016/TJOI2016]序列(Cdq+dp)
题面 luogu 题解 \(Cdq分治+dp\) \(mx[i],mn[i]\)分别表示第\(i\)位最大,最小能取到多少 那么有 \(j < i\) \(mx[j] \le a[i]\) \( ...
随机推荐
- (转)Gmail,你必须了解的12个邮件编码问题
转载地址:http://www.maildesign.cn/archives/1537 1.Gmail 不支持style=” display:none”2.Gmail不支持内嵌式CSS样式3.Gmai ...
- 一个小白的测试环境docker化之路
本文来自网易云社区 作者:叶子 学习docker搭建测试环境断断续续也有三个多月了,希望记录一下这个过程.常言道,总结过去,展望未来嘛~文章浅显,还望各位大神路过轻拍. 按照国际惯例,先说一下背景: ...
- 从细节处谈Android冷启动优化
本文来自网易云社区 Android APP冷启动优化,对于Android开发同学而言可能是个老生常谈的技优了. 之所以花时间写一篇冷启动优化的文章: 我想从另外一个角度来说冷启动优化,如题所述,从细节 ...
- SpringBoot入门(四)——自动配置
本文来自网易云社区 SpringBoot之所以能够快速构建项目,得益于它的2个新特性,一个是起步依赖前面已经介绍过,另外一个则是自动配置.起步依赖用于降低项目依赖的复杂度,自动配置负责减少人工配置的工 ...
- git 操作几个命令
git clone ssh://lijianfeng@192.168.1.246:29418/GMGameSDK压栈:git stash查状态:git status切换到要修改的提交:git reb ...
- TPO-11 C2 Work for the biology committee
committee 委员会 representative 代表 department secretary 系里的秘书 applicant 申请人 TPO-11 C2 Work for the biol ...
- Python 作用域和命名空间
在介绍类之前,我首先要告诉你一些Python的作用域规则.类定义对命名空间有一些巧妙的技巧,你需要知道作用域和命名空间如何工作才能完全理解正在发生的事情.顺便说一下,关于这个主题的知识对任何高级Pyt ...
- 在deepin系统中制作桌面快捷方式
在使用deepin-wine 安装一些软件的时候,每次启动都需要到.deepinwine目录下运行deepin-wine xx.exe.笔者在安装过HeidiSql之后,一直苦于这种情况.比较好的解决 ...
- 【CSVRead】-jmeter
csv read 读取文件
- django启动创建用户失败
a django应用启动 b 访问127.0.0.1:8000,报错信息如下,原因为没有这个用户需要创建下用户 c 创建用户过程中报错原因是因为添加了app需要告诉django,这个 模型发生了改变, ...