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[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) 动态开点)的更多相关文章
- tyvj P1716 - 上帝造题的七分钟 二维树状数组区间查询及修改 二维线段树
P1716 - 上帝造题的七分钟 From Riatre Normal (OI)总时限:50s 内存限制:128MB 代码长度限制:64KB 背景 Background 裸体就意味着 ...
- 洛谷 P4093: bzoj 4553: [HEOI2016/TJOI2016]序列
题目传送门:洛谷P4093. 题意简述: 给定一个长度为 \(n\) 的序列 \(a\). 同时这个序列还可能发生变化,每一种变化 \((x_i,y_i)\) 对应着 \(a_{x_i}\) 可能变成 ...
- Luogu P4093 [HEOI2016/TJOI2016]序列 dp套CDQ
题面 好久没写博客了..最近新学了CDQ...于是就来发一发一道CDQ的练习题 看上去就是可以dp的样子. 设\(dp_{i}\)为以i结尾的最长不下降序列. 易得:\(dp_{i}\)=\(max( ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...
- [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)
[BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】
题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...
- [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】
题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...
- 【序列操作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 ...
随机推荐
- 【转】Python之日期与时间处理模块(date和datetime)
[转]Python之日期与时间处理模块(date和datetime) 本节内容 前言 相关术语的解释 时间的表现形式 time模块 datetime模块 时间格式码 总结 前言 在开发工作中,我们经常 ...
- 用nodejs做一下发送邮件例子
var nodemailer = require("nodemailer"); var transport = nodemailer.createTransport("S ...
- Python3学习笔记21-实例属性和类属性
由于Python是动态语言,根据类创建的实例可以任意绑定属性. 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Student(object): def __init__(se ...
- S5PV210的根文件系统制作
一.移植BusyBox1.下载BusyBox的源代码下载地址:http://www.busybox.net/downloads/,此处下载busybox-1.20.2.tar.bz2.2.解压并进入目 ...
- JS/Jquery版本的俄罗斯方块(附源码分析)
转载于http://blog.csdn.net/unionline/article/details/63250597 且后续更新于此 1.前言 写这个jQuery版本的小游戏的缘由在于我想通过从零到有 ...
- 容器平台选型的十大模式:Docker、DC/OS、K8S 谁与当先?【转】
网易企业服务2017-10-13 无论是在社区,还是在同客户交流的过程中,总会被问到到底什么时候该用 Docker?什么时候用虚拟机?如果使用容器,应该使用哪个容器平台? 显而易见,我不会直接给大家一 ...
- h5之js生成二维码
目录架构: index.html <!DOCTYPE> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang=& ...
- vue之导入Bootstrap以及jQuery的两种方式
Vue引入bootstrap主要有两种方法 方法一:在main.js中引入,此方法导入的bootstrap中对于html,body的一些预设置的css样式可能无效. 一.引入jQuery 在当前项目的 ...
- 并发之AQS原理(一) 原理介绍简单使用
并发之AQS原理(一) 如果说每一个同步的工具各有各的强大,那么这个强大背后是一个相同的动力,它就是AQS. AQS是什么 AQS是指java.util.concurrent.locks包里的Abst ...
- 性能测试七:jmeter进阶之文件上传下载、定时器
一.上传下载 上传: 1,POST请求,勾选 use …for post 2,同请求一起发送文件里,填写文件名称,参数名称 3,MIME类型: application/octet-stream(非必须 ...