题目链接:BZOJ 洛谷

\(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\)

 for(int j=1; j<i; ++j)
if(a[j]<=minv[i]&&maxv[j]<=a[i])//序列只会变换一次
dp[i]=max{dp[j]+1};

转移要满足两个条件:\(a[j]<=minv[i]\ \&\&\ maxv[j]<=a[i]\)

一个二维偏序问题,CDQ、树套树都可以。

拿\(minv[x]\)和\(a[y]\)作为两个坐标轴,\(dp[j]\)表示其上一点\((A[j],maxv[j])\).

这样就成了一个二维平面,可以向其中插入一些点dp[i],询问一个矩形区域(也是一段前缀)中某点最大值

线段树套线段树 树状数组套线段树都可做 复杂度\(O(nlog^2n)\)

后者时间还可以

树状数组套线段树:

//企图二维树状数组 但动态开点的话 中间一段没有的区间会中断y方向的Query..
#include<cstdio>
#include<cctype>
#include<algorithm>
#define gc() getchar()
#define now node[rt]
#define lson l,m,node[rt].ls
#define rson m+1,r,node[rt].rs
#define lb(x) ((x)&-(x))
const int N=1e5+5; int n,m,A[N],minv[N],maxv[N],MaxV,MaxA;
namespace Tree_2D
{
struct Seg_Tree
{
struct Node
{
int maxv,ls,rs;
}node[N<<6];//还要再小点。。不然BZOJ上依旧MLE
inline int new_Node()
{
static int cnt=0;
return ++cnt;
}
void Insert(int l,int r,int &rt,int p,int v)
{
if(!rt) rt = new_Node();
now.maxv = std::max(now.maxv, v);
if(l<r)
{
int m=l+r>>1;
if(p<=m) Insert(lson,p,v);
else Insert(rson,p,v);
}
}
int Query(int l,int r,int rt,int L,int R)
{
if(!rt) return 0;
if(L<=l && r<=R) return now.maxv;
int m=l+r>>1;
if(L<=m)
if(m<R) return std::max(Query(lson,L,R),Query(rson,L,R));
else return Query(lson,L,R);
return Query(rson,L,R);
}
}t;
struct Bit
{
int root[N];
void Insert(int p,int y,int v)
{
while(p<=MaxV)
t.Insert(1,MaxA,root[p],y,v), p+=lb(p);
}
int Query(int p,int y)
{
int res=0;
while(p)
res=std::max(res,t.Query(1,MaxA,root[p],1,y)), p-=lb(p);
return res;
}
}t2D;
}
#undef now
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
} int main()
{
n=read(),m=read();
for(int i=1; i<=n; ++i)
maxv[i]=minv[i]=A[i]=read(), MaxA=std::max(MaxA,A[i]);
for(int x,y,i=1; i<=m; ++i)
x=read(), y=read(), maxv[x]=std::max(maxv[x],y), minv[x]=std::min(minv[x],y);
for(int i=1; i<=n; ++i) MaxV=std::max(MaxV,maxv[i]);
int ans=0;
for(int v,i=1; i<=n; ++i)
{
v = Tree_2D::t2D.Query(minv[i],A[i]) + 1;
Tree_2D::t2D.Insert(A[i],maxv[i],v);
ans=std::max(ans,v);
}
printf("%d",ans); return 0;
}

二维线段树:

/*
BZOJ上直接MLE...洛谷P4093 4508ms(比Bit套Segtree慢3倍+) 293.33MB
空间消耗比较大 写指针吧。。
*/
#include<cstdio>
#include<cctype>
#include<algorithm>
#define gc() getchar()
#define lson l,m,rt->ls
#define rson m+1,r,rt->rs
const int N=1e5+5; int n,m,A[N],maxv[N],minv[N],MaxA,MaxV;
namespace Seg_Tree2D
{
struct Node
{
int maxv;
Node *ls,*rs;
Node(): maxv(0),ls(NULL),rs(NULL) { }
}pool[N<<7];//(logN)^2=256(2^8) 开得小点吧要不空间会炸
struct Node2D
{
Node *root;
Node2D *ls,*rs;
Node2D(): root(NULL),ls(NULL),rs(NULL) { }
}pool2D[N<<1],*root;
inline Node *new_Node()
{
static int cnt=0;
return &pool[cnt++];
}
inline Node2D *new_Node2D()
{
static int cnt=0;
return &pool2D[cnt++];
}
Node2D *Build(int l,int r)
{
Node2D *rt = new_Node2D();
if(l<r)
{
int m=l+r>>1;
rt->ls = Build(l,m);
rt->rs = Build(m+1,r);
}
return rt;
}
int Query(int l,int r,Node *rt,int L,int R)
{
if(!rt) return 0;
if(L<=l && r<=R) return rt->maxv;
int m=l+r>>1;
if(L<=m)
if(m<R) return std::max(Query(lson,L,R),Query(rson,L,R));
else return Query(lson,L,R);
return Query(rson,L,R);
}
int Query2D(int l,int r,Node2D *rt,int L,int R,int y1,int y2)
{
if(L<=l && r<=R) return Query(1,MaxA,rt->root,y1,y2);
int m=l+r>>1;
if(L<=m)
if(m<R) return std::max(Query2D(lson,L,R,y1,y2),Query2D(rson,L,R,y1,y2));
else return Query2D(lson,L,R,y1,y2);
return Query2D(rson,L,R,y1,y2);
}
void Insert(int l,int r,Node *&rt,int p,int v)
{
if(!rt) rt = new_Node();//!
rt->maxv = std::max(rt->maxv, v);
if(l<r)
{
int m=l+r>>1;
if(p<=m) Insert(lson,p,v);
else Insert(rson,p,v);
}
}
void Insert2D(int l,int r,Node2D *rt,int p,int y,int v)
{
Insert(1, MaxA, rt->root, y, v);
if(l<r)
{
int m=l+r>>1;
if(p<=m) Insert2D(lson,p,y,v);
else Insert2D(rson,p,y,v);
}
}
void Init()
{
root = Build(1,MaxV);
}
int Query_Max(int l,int r,int y1,int y2)
{
return Query2D(1,MaxV,root,l,r,y1,y2);
}
void Insert_Node(int x,int y,int v)
{
Insert2D(1,MaxV,root,x,y,v);
}
}
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
} int main()
{
n=read(),m=read();
for(int i=1; i<=n; ++i)
maxv[i]=minv[i]=A[i]=read(), MaxA=std::max(MaxA,A[i]);
for(int x,y,i=1; i<=m; ++i)
x=read(), y=read(), maxv[x]=std::max(maxv[x],y), minv[x]=std::min(minv[x],y);
for(int i=1; i<=n; ++i) MaxV=std::max(MaxV,maxv[i]);
Seg_Tree2D::Init();
int ans=0;
for(int v,i=1; i<=n; ++i)
{
v = Seg_Tree2D::Query_Max(1,minv[i],1,A[i]) + 1;
Seg_Tree2D::Insert_Node(A[i],maxv[i],v);
ans=std::max(ans,v);
}
printf("%d",ans); return 0;
}

BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)的更多相关文章

  1. tyvj P1716 - 上帝造题的七分钟 二维树状数组区间查询及修改 二维线段树

    P1716 - 上帝造题的七分钟 From Riatre    Normal (OI)总时限:50s    内存限制:128MB    代码长度限制:64KB 背景 Background 裸体就意味着 ...

  2. 洛谷 P4093: bzoj 4553: [HEOI2016/TJOI2016]序列

    题目传送门:洛谷P4093. 题意简述: 给定一个长度为 \(n\) 的序列 \(a\). 同时这个序列还可能发生变化,每一种变化 \((x_i,y_i)\) 对应着 \(a_{x_i}\) 可能变成 ...

  3. Luogu P4093 [HEOI2016/TJOI2016]序列 dp套CDQ

    题面 好久没写博客了..最近新学了CDQ...于是就来发一发一道CDQ的练习题 看上去就是可以dp的样子. 设\(dp_{i}\)为以i结尾的最长不下降序列. 易得:\(dp_{i}\)=\(max( ...

  4. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  5. [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)

    [BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...

  6. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

  7. [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

    题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...

  8. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

  9. 【序列操作IV】树状数组套线段树/树套树

    题目描述 给出序列 a1,a2,…,an(0≤ai≤109),有关序列的两种操作. 1. ai(1≤i≤n)变成 x(0≤x≤109). 2. 求 al,al+1,…,ar(1≤l≤r≤n)第 k(1 ...

随机推荐

  1. malloc()函数(Linux程序员手册)及函数的正确使用【转】

    转自:https://blog.csdn.net/david_xtd/article/details/7311204 名称 malloc,free,calloc,realloc--分配和释放动态内存 ...

  2. 蓝牙Bluetooth技术手册规范下载【转】

    蓝牙Bluetooth技术手册规范下载 http://www.crifan.com/summary_bluetooth_specification_download/ [背景] 之前就已经整理和转帖了 ...

  3. 写好shell脚本的13个技巧【转】

    有多少次,你运行./script.sh,然后输出一些东西,但却不知道它刚刚都做了些什么.这是一种很糟糕的脚本用户体验.我将在这篇文章中介绍如何写出具有良好开发者体验的 shell 脚本. 产品的最终用 ...

  4. C++ virtual函数重写,在继承的时候没有在函数前写virtual关键字也依然是虚函数吗?

    比如: class Base { Base() {}; ~Base() {}; virtual void Init(); }; class Derived:public Base { virtual ...

  5. select 不要 用*

    背景 说实在的,这有什么好记录的呢.记录这个有啥用,真是技术人员的吹毛求疵.说起来,就是给人装有用吧.既然记录了,也想个相关的段子吧.曾经有个同事写了个sql,效率极差,来了个女同事,竟然解决了,问题 ...

  6. centos6.5环境基于corosync+cman+rgmanager实现RHCS及iscsi+gfs2+clvm的文件系统集群

    centos6.5环境基于corosync+cman+rgmanager实现RHCS及iscsi+gfs2+clvm文件系统集群 一.环境准备 服务器列表: ansible server : 192. ...

  7. 转载:Java高并发,如何解决,什么方式解决

    原文:https://www.cnblogs.com/lr393993507/p/5909804.html 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并 ...

  8. 转载:2.2.3 配置项的注释《深入理解Nginx》(陶辉)

    原文:https://book.2cto.com/201304/19628.html 如果有一个配置项暂时需要注释掉,那么可以加"#"注释掉这一行配置.例如: #pid       ...

  9. robotium之webview元素处理

    今天写robotium脚本发现,用uiautomatorviewer定位百度贴吧的登录框是无法定位的,如图: 明显无法定位用户名.密码输入框,无法定位元素那就无法对控件无法操作 如何定位webview ...

  10. Gradient Domain Guided Image Filtering(梯度域导向滤波)

    作者提出了一种新的梯度域引导图像滤波器,通过将明确的一阶边缘感知约束结合到现有的引导图像滤波器中. matlab代码实现 转载至:https://blog.csdn.net/majinlei121/a ...