[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]\) \( ...
随机推荐
- JMeter性能测试的基础知识和个人理解
JMeter性能测试的基础知识和个人理解 1. JMeter的简介 JMeter是Apache组织开发的开源项目,设计之初是用于做性能测试的,同时它在实现对各种接口的调用方面做的比较成熟,因此,常 ...
- 【CentOS】下安装RabbitMQ教程
系统版本: 安装依赖: 由于RabbitMQ依赖Erlang, 所以需要先安装Erlang. Erlang的安装方式大概有两种: (1) Erlang Solution安装(推荐) wget http ...
- Linux命令应用大词典-第7章 字符串、文件和命令查找
7.1 grep:字符串.文件和命令的查找 7.2 egrep:在文件或标准输入中查找模式 7.3 fgrep:在每个文件或是标准输入中查找模式 7.4 find:列出文件系统内符合条件的文件 7.5 ...
- ajax 个人理解 学习笔记
W:Ajax Q:异步网络请求.无刷新请求数据. W:ajax的实现流程如下: Q: 创建XHR对象 调用open()方法,创建请求 调用send()方法,发送请求 捕获请求状态,判断请求结果 获取数 ...
- 解析范式(1NF-4NF)
亲爱的盆友们~又是新的一年,你,准备好新的学习计划了吗~?是读书100本,还是考上5个证?嘛~不管怎么说,角落里那一堆蒙尘的计划表好像在昭示着这仍然是一个充满朝气又艰难的9102年呢!总之,先把#技本 ...
- 关于ES6-{块级作用域 let const 解构赋值 数组 字符串 函数的扩展 箭头函数}
关于ES6 块级作用域 任何一对花括号({})中的语句集都属于一个块,在块中声明的变量在代码块外都是不可访问的,称之为块级作用域,ES5以前没有块级作用域 let let 是ES6新增的声明变量的一种 ...
- Code obfuscatio (翻译!)
Description Kostya likes Codeforces contests very much. However, he is very disappointed that his so ...
- 福大软工1816:Alpha(7/10)
Alpha 冲刺 (7/10) 队名:Jarvis For Chat 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务: 文字/口头描述: 1.完成 ...
- object-oriented 第二次作业(2)
面向对象程序设计自学计划 由于我的英文实在是很差,所以我就没有去考虑看英文的课程视频.网络上的课程有很多,什么学校的也有,一开始我不知道该如何开始选择课程.感觉每个都还可以.后来在群里的看到别人推荐的 ...
- alpha-4
前言 失心疯病源4 团队代码管理github 站立会议 队名:PMS 530雨勤(组长) 今天完成了那些任务 19:00~21:50 利用背景相减法完成背景构建与更新模块,查找关于blob更多的论文资 ...