题目链接: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. 【转】PyDev Eclipse使用技巧说明

    PyDev Package Explorer 创建项目 在开展工作之前,需要创建一个新的项目.在 Eclipse 菜单栏中,选择 File > New > Project > Pyd ...

  2. ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(4)- 其它

    1. 前言 2.可配置的指令使能/禁用控制和trap控制 指令使能/禁用 当指令被禁用,则这条指令就会变成未定义 指令Trap控制 控制某条或某些指令在运行时进入陷阱,进入陷阱的指令会产生trap异常 ...

  3. root权限使用vim不能修改权限

    1.背景: 有时候我们会发现使用root权限不能修改某个文件,大部分原因是曾经使用chattr将文件锁定了 2.chattr命令介绍: 用来改变文件属性,能防止root用户误删文件等作用 3.使用方法 ...

  4. vue系列之Vue-cli

    Vue-cli是Vue的脚手架工具 vue-cli 地址:https://github.com/vuejs/vue-cli 安装 npm install -g vue-cli 使用 vue init ...

  5. bert 词典扩充方案

  6. python中type、object与class之间关系(一切皆对象)

    object是最顶层基类 object是type的实例,而type又继承object type是自身的实例 >>> class Student: ... pass ... >& ...

  7. iOS学习笔记之异步图片下载

    写在前面 在iOS开发中,无论是在UITableView还是在UICollectionView中,通过网络获取图片设置到cell上是较为常见的需求.尽管有很多现存的第三方库可以将下载和缓存功能都封装好 ...

  8. pytest十一:函数传参和 firture 传参数 request

    为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数.比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登录函数就行.但是登录 ...

  9. python 全栈开发,Day36(作业讲解(大文件下载以及进度条展示),socket的更多方法介绍,验证客户端链接的合法性hmac,socketserver)

     先来回顾一下昨天的内容 黏包现象粘包现象的成因 : tcp协议的特点 面向流的 为了保证可靠传输 所以有很多优化的机制 无边界 所有在连接建立的基础上传递的数据之间没有界限 收发消息很有可能不完全相 ...

  10. ERP商品类型管理相关业务处理(三十五)

    根据类型编号获取父类名称 -- ============================================= CREATE FUNCTION [dbo].[FN_getParentTyp ...