Luogu P4093 [HEOI2016/TJOI2016]序列 dp套CDQ
[题面](https://www.luogu.org/problemnew/show/P4093)
好久没写博客了..最近新学了CDQ...于是就来发一发一道CDQ的练习题
看上去就是可以dp的样子。
设\(dp_{i}\)为以i结尾的最长不下降序列。
易得:\(dp_{i}\)=\(max(dp_{j})+1\)\((j<=i\)&&\(Max_{j}<=a_{i}\)&&\(a_{j}<=Min_{i})\)
\(Max_{i}\)和\(Min_{i}\)表示第i个点所有变化中的最大值和最小值。
我们考虑用一个什么东西来维护这个dp。
我的第一反应是树状数组套动态开点线段树,而且写那玩意应该也不会太长。
突然想到最近学了CDQ。
于是讲下CDQ怎么搞。
因为有两个两边不是同一个数组的条件,所以我们在solve的时候,要对\([l,mid]\)和\([mid+1,r]\)的根据不同的两个数组sort下,然后用个树状数组维护前缀max,算下左边对右边的贡献。
然后因为是dp,所以我们不能直接分治\([l,mid]\)和\([mid+1,r]\)然后合并,我们应该先分治\([l,mid]\)然后算好\([l,mid]\)对\([mid+1,r]\)的贡献,然后再去分治\([mid+1,r]\) (记得去做\([mid+1,r]\)前先把数组\([mid+1,r]\)恢复)
#include<cstdio>
#include<algorithm>
#include<string>
#define ll long long
#define For(i,x,y) for (register int i=(x);i<=(y);i++)
#define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
#define cross(i,k) for (register int i=first[k];i;i=last[i])
using namespace std;
inline ll read(){
ll x=0;int ch=getchar(),f=1;
while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
if (ch=='-'){f=-1;ch=getchar();}
while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
inline ll min(ll a,ll b){return a<b?a:b;}
inline ll max(ll a,ll b){return a>b?a:b;}
const int N = 100010;
struct node{
int max,min,v,ans,id;
}a[N];
int n,m,x,y,ans,Max;
int c[N];
inline void Add(int x,int y){for (;x<=Max;x+=x&(-x)) c[x]=max(c[x],y);}
inline int Query(int x){int ans=0;for (;x;x-=x&(-x)) ans=max(ans,c[x]);return ans;}
inline void Clear(int x){for (;x<=Max;x+=x&(-x)) c[x]=0;}
inline bool cmp1(node a,node b){return a.max<b.max;}
inline bool cmp2(node a,node b){return a.v<b.v;}
inline bool cmp3(node a,node b){return a.id<b.id;}
inline void CDQ(int l,int r){
if (l==r) return;
int mid=l+r>>1;
CDQ(l,mid);
sort(a+l,a+mid+1,cmp1),sort(a+mid+1,a+r+1,cmp2);
int L=l,R=mid+1;
for (;L<=mid&&R<=r;R++){
for (;a[L].max<=a[R].v&&L<=mid;L++) Add(a[L].v,a[L].ans);
a[R].ans=max(a[R].ans,Query(a[R].min)+1);
}
For(i,R,r) a[i].ans=max(a[i].ans,Query(a[i].min)+1);
For(i,l,L) Clear(a[i].v);
sort(a+mid+1,a+r+1,cmp3);
CDQ(mid+1,r);
}
int main(){
n=read(),m=read();
For(i,1,n) a[i].v=a[i].max=a[i].min=read(),a[i].id=i;
For(i,1,m){
x=read(),y=read();
a[x].max=max(a[x].max,y),a[x].min=min(a[x].min,y);
}
For(i,1,n) Max=max(Max,max(a[i].v,a[i].min)),a[i].ans=1;
//For(i,1,n) printf("%d %d %d\n",a[i].v,a[i].min,a[i].max);puts("");
CDQ(1,n);
For(i,1,n) ans=max(ans,a[i].ans);
//For(i,1,n) printf("%d %d %d %d\n",a[i].v,a[i].min,a[i].max,a[i].ans);
printf("%d",ans);
}
Luogu P4093 [HEOI2016/TJOI2016]序列 dp套CDQ的更多相关文章
- 洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP
洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他. 玩具上有一个数列,数列中某些项的值可能会 ...
- 洛谷 P4093 [HEOI2016/TJOI2016]序列 解题报告
P4093 [HEOI2016/TJOI2016]序列 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一 ...
- 洛谷 P4093 [HEOI2016/TJOI2016]序列(Cdq+dp)
题面 luogu 题解 \(Cdq分治+dp\) \(mx[i],mn[i]\)分别表示第\(i\)位最大,最小能取到多少 那么有 \(j < i\) \(mx[j] \le a[i]\) \( ...
- BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)
题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...
- 洛谷P4093 [HEOI2016/TJOI2016]序列
题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一个值发生变化.现在佳媛姐姐已经研究出了所有变化的可能性, ...
- BZOJ4553/洛谷P4093 [HEOI2016/TJOI2016]序列 动态规划 分治
原文链接http://www.cnblogs.com/zhouzhendong/p/8672434.html 题目传送门 - BZOJ4553 题目传送门 - 洛谷P4093 题解 设$Li$表示第$ ...
- P4093 [HEOI2016/TJOI2016]序列
题目链接 题意分析 我们假设每一个数都有一个变动范围\([L_i,R_i]\) 那么我们令\(dp[i]\)表示以\(i\)结尾的最长不下降子序列的长度 那么就是\(dp[i]=max\{dp[j]+ ...
- 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; ...
- [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)
题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...
随机推荐
- jQuery操作Table学习总结[转]
<style type="text/css"> .hover { } </style>< ...
- 新疆大学ACM-ICPC程序设计竞赛五月月赛(同步赛) F.猴子排序的期望
题目链接:https://www.nowcoder.com/acm/contest/116/F 题目描述 我们知道有一种神奇的排序方法叫做猴子排序,就是把待排序的数字写在卡片上,然后让猴子把卡片扔在空 ...
- python—RE正则表达式
re正则表达式 正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列的字节码,然后由用 C 编写的 ...
- vue路由-基础
安装 1.直接下载 / CDN https://unpkg.com/vue-router/dist/vue-router.js 在 Vue 后面加载 vue-router,它会自动安装的: <s ...
- [Leetcode Week12]Unique Paths II
Unique Paths II 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/unique-paths-ii/description/ Descrip ...
- Kotlin 学习使用之旅(二)
为什么从二开始呢?再此之前已经有了一篇了,那是刚知道kotlin的时候草(chao)来(chao)的并且学习一篇, 这次是自己在项目中正式使用并且遇到的一些问题记录,供kotlin新入门的童鞋参考,避 ...
- 【Educationcal Codeforces Round 21】
这场edu我原本以为能清真一点…… 后来发现不仅是七题 还有各种奇奇怪怪的骚操作…… A. 随便枚举 #include<bits/stdc++.h> using namespace std ...
- Github精选 – 适合移动端的HTML5 Datepicker
2016-01-12 (updated: 2017-01-07) 15731 通过 HTML5 的 <input> 新属性可以简单方便地调用手机的原生 Datepicker,但功能较弱, ...
- jquery文档加载几种写法,图片加载写法
jquery文档加载写法: $(function(){ }) ; //个人最常使用方式 $(document).ready(function(){ }); //调用文档对象下的ready方法传入一个函 ...
- POJ 1177 Picture(线段树:扫描线求轮廓周长)
题目链接:http://poj.org/problem?id=1177 题目大意:若干个矩形,求这些矩形重叠形成的图形的轮廓周长. 解题思路:这里引用一下大牛的思路:kuangbin 总体思路: 1. ...