[题面](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的更多相关文章

  1. 洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP

    洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他. 玩具上有一个数列,数列中某些项的值可能会 ...

  2. 洛谷 P4093 [HEOI2016/TJOI2016]序列 解题报告

    P4093 [HEOI2016/TJOI2016]序列 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一 ...

  3. 洛谷 P4093 [HEOI2016/TJOI2016]序列(Cdq+dp)

    题面 luogu 题解 \(Cdq分治+dp\) \(mx[i],mn[i]\)分别表示第\(i\)位最大,最小能取到多少 那么有 \(j < i\) \(mx[j] \le a[i]\) \( ...

  4. 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[ ...

  5. 洛谷P4093 [HEOI2016/TJOI2016]序列

    题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一个值发生变化.现在佳媛姐姐已经研究出了所有变化的可能性, ...

  6. BZOJ4553/洛谷P4093 [HEOI2016/TJOI2016]序列 动态规划 分治

    原文链接http://www.cnblogs.com/zhouzhendong/p/8672434.html 题目传送门 - BZOJ4553 题目传送门 - 洛谷P4093 题解 设$Li$表示第$ ...

  7. P4093 [HEOI2016/TJOI2016]序列

    题目链接 题意分析 我们假设每一个数都有一个变动范围\([L_i,R_i]\) 那么我们令\(dp[i]\)表示以\(i\)结尾的最长不下降子序列的长度 那么就是\(dp[i]=max\{dp[j]+ ...

  8. 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; ...

  9. [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)

    题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...

随机推荐

  1. jQuery右侧悬浮楼层滚动 电梯菜单

    http://www.kaiu.net/effectCon.aspx?id=2198 <!doctype html> <html> <head> <meta ...

  2. 编写jquery Plugin

    编写jquery插件的原则 1.给$.fn绑定函数,实现插件的代码逻辑 2.插件函数最后要return this,以支持链式调用 3.插件函数要有默认值,绑定在$.fn.<pluginName& ...

  3. perl发送post数据

    把post数据写进一个匿名数组里就行 #!/usr/bin/env perl -w use strict; use LWP::UserAgent; my $ua = LWP::UserAgent-&g ...

  4. shell下在while循环中使用ssh命令的问题

    1 现象描述 最近使用ssh批量执行命令(已经做了密钥互信了),脚本读取配置文件中的主机列表(内容为每行一台主机IP地址),然后执行,可是每次只是执行第一台,就退出循环了. 2 排查思路 由于脚本比较 ...

  5. Oracle 合并 merger into

    merge into copy_emp1 c  using employees e  on (c.employee_id=e.employee_id)when matched then  update ...

  6. vue有关绑定的知识点

    一.v-bind绑定class 1.对象的形式 <div :class="{text-danger:true}"></div> 数组形式绑定class &l ...

  7. android intent 传数据

    1. 基本数据类型 Intent intent = new Intent(); intent.setClass(activity1.this, activity2.class); //描述起点和目标 ...

  8. [New learn] NSOperation基本使用

    1.简介 NS(基于OC语言)是对GCD(基于C语言)的封装,让开发者能够更加友好的方便的去使用多线程技术. 2.NSOperation的基本使用 NSOperation是抽象类,所以如果要使用NSO ...

  9. python--lxml

    ''' xpath语法: /:在子节点里面找 //:在子子孙孙里面找 //div:查找当前网页的所有div标签 //div/p:先查找所有div标签,再找div的子标签中的p标签 //div//p:现 ...

  10. position:fixed部分版本的浏览器不支持

    ie6-ie8浏览器不支持这个属性 .fixed{         position:fixed; /*对于火狐等其他浏览器需要设置的*/         top:700px;  /*同上*/     ...