2021.12.07 [TJOI2013]最长上升子序列(Treap+DP)

https://www.luogu.com.cn/problem/P4309

题意:

给定一个序列,初始为空。现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,我们都想知道此时最长上升子序列长度是多少?

分析:

对于第 \(i\) 个插进去的数字 \(i\) ,插到了第 \(x\) 位,则对于前 \(i\) 个数字的最长上升子序列 \(f[i]\) :

\[f[i]=\max(f[1]+1,f[2]+1,f[3]+1,\cdots,f[i-1]+1)\\
=\max(f[1],f[2],f[3],\cdots,f[i-1])+1
\]

所以只需要最后求一边最长上升子序列就行。

这里可以使用树状数组或者硬算。

插入那就按照子树大小分割,一步步插入就行。

注:如果想使用 \(M\times v_1+v_2\) 这个方法插入,这是不行滴~比如:我现在第一位插入,又在第一位插入,在第二位插入,在第一位插入。按照这个方法插入结果是 4 2 1 3 ,而真正结果是 4 2 3 1

代码如下:

0pts:

Treap+树状数组

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std; #define int long long
const int N=1e5+10;
int n,cnt,root,son[N][2],sizei[N],same[N],val[N],key[N],trueval[N];
int t[N]; inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline void update(int x){
sizei[x]=sizei[son[x][0]]+sizei[son[x][1]]+same[x];
}
inline void rotate(int &x,int flag){
int y=son[x][flag^1];
int change=son[y][flag];
son[x][flag^1]=change;
son[y][flag]=x;
update(x);
update(y);
x=y;
}
inline void insert(int &x,int vali,int truevali){
if(!x){
x=++cnt;
sizei[x]=same[x]=1;
val[x]=vali;
trueval[x]=truevali;
key[x]=rand();
return ;
}
if(val[x]==vali)return (void)(++sizei[x],++same[x]);
int flag=vali>val[x];
insert(son[x][flag],vali,truevali);
if(key[x]<key[son[x][flag]])rotate(x,flag^1);
update(x);
}
inline int rank_score(int x,int k){
if(!x)return 0;
if(sizei[son[x][0]]>=k)return rank_score(son[x][0],k);
else if(sizei[son[x][0]]+same[x]>=k)return trueval[x];
else return rank_score(son[x][1],k-sizei[son[x][0]]-same[x]);
}
inline int lowbit(int x){
return x&-x;
}
inline void add(int x,int k){
for(int i=x;i<=n;i+=lowbit(i))t[i]=max(t[i],k);
}
inline int query(int x){
int fin=0;
for(int i=x;i>0;i-=lowbit(i))fin=max(fin,t[i]);
return fin;
} signed main(){
n=read();
for(int i=1;i<=n;i++){
int x=read();
x=x*(N-10)-i;
insert(root,x,i);
}
for(int i=1;i<=n;i++){
int x=rank_score(root,i);
int y=query(x-1)+1;
//cout<<x<<" "<<y<<endl;
cout<<y<<endl;
add(x,y);
}
return 0;
}

100pts:

Treap+硬算

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std; #define int long long
const int N=1e5+10;
int n,cnt,root,son[N][2],sizei[N],same[N],val[N],key[N],trueval[N];
int t[N],a[N],ans[N],b[N],f[N]; inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline void update(int x){
sizei[x]=sizei[son[x][0]]+sizei[son[x][1]]+same[x];
}
inline void rotate(int &x,int flag){
int y=son[x][flag^1];
int change=son[y][flag];
son[x][flag^1]=change;
son[y][flag]=x;
update(x);
update(y);
x=y;
}
inline void insert(int &x,int vali,int truevali){
if(!x){
x=++cnt;
sizei[x]=same[x]=1;
val[x]=vali;
trueval[x]=truevali;
key[x]=rand();
return ;
}
int flag=0;
if(vali<=sizei[son[x][0]])insert(son[x][0],vali,truevali),flag=0;
else insert(son[x][1],vali-sizei[son[x][0]]-same[x],truevali),flag=1;
if(key[x]<key[son[x][flag]])rotate(x,flag^1);
update(x);
}
inline void work(int x){
if(son[x][0])work(son[x][0]);
a[++n]=trueval[x];
if(son[x][1])work(son[x][1]);
} signed main(){
n=read();
for(int i=1;i<=n;i++){
int x=read();
//x=x*(N-10)-i;
insert(root,x,i);
}
n=0;
work(root);
for(int i=1;i<=n;i++)b[i]=n+1;
//for(int i=1;i<=n;i++)cout<<a[i]<<" ";cout<<endl;//
for(int i=1;i<=n;i++){
int x=lower_bound(b,b+n+1,a[i])-b;
f[i]=x;
b[f[i]]=min(b[f[i]],a[i]);
ans[a[i]]=f[i];
//cout<<x<<" "<<ans[a[i]]<<endl;//
}
for(int i=1;i<=n;i++)ans[i]=max(ans[i],ans[i-1]);
for(int i=1;i<=n;i++)cout<<ans[i]<<endl;
return 0;
}

2021.12.07 [TJOI2013]最长上升子序列(Treap+DP)的更多相关文章

  1. 2021.12.07 P4291 [HAOI2008]排名系统(Treap)

    2021.12.07 P4291 [HAOI2008]排名系统(Treap) https://www.luogu.com.cn/problem/P4291 双倍经验: https://www.luog ...

  2. BZOJ 3173: [Tjoi2013]最长上升子序列 [splay DP]

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1613  Solved: 839[Submit][St ...

  3. BZOJ3173 TJOI2013最长上升子序列(Treap+ZKW线段树)

    传送门 Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input ...

  4. 【bzoj3173】[Tjoi2013]最长上升子序列 Treap

    题目描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? 输入 第一行一个整数N,表示我们要 ...

  5. bzoj 3173: [Tjoi2013]最长上升子序列【dp+线段树】

    我也不知道为什么把题看成以插入点为结尾的最长生生子序列--还WA了好几次 先把这个序列最后的样子求出来,具体就是倒着做,用线段树维护点数,最开始所有点都是1,然后线段树上二分找到当前数的位置,把这个点 ...

  6. [BZOJ3173][Tjoi2013]最长上升子序列

    [BZOJ3173][Tjoi2013]最长上升子序列 试题描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上 ...

  7. BZOJ 3173: [Tjoi2013]最长上升子序列

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1524  Solved: 797[Submit][St ...

  8. Bzoj 3173: [Tjoi2013]最长上升子序列 平衡树,Treap,二分,树的序遍历

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1183  Solved: 610[Submit][St ...

  9. BZOJ 3173: [Tjoi2013]最长上升子序列( BST + LIS )

    因为是从1~n插入的, 慢插入的对之前的没有影响, 所以我们可以用平衡树维护, 弄出最后的序列然后跑LIS就OK了 O(nlogn) --------------------------------- ...

随机推荐

  1. 嵌入式无操作系统下管理内存和队列(类UCOS II思想)

    例子:存储日志,最多存128条,每条最大1MB. 内存方面 因为嵌入式不适合用动态内存,会产生碎片.这里我们用 u8 data[LOG_SIZE];开辟固定128MB的内存区,再对其分为128个1MB ...

  2. GitHub还能这样玩,这次我真是开了眼了

    哈喽,大家好,我是指北君. 我会一直在"开源指北"公众号给大家分享各种有趣. 实用与最前沿的开源项目,还有各种互联网干货, 今天主要给大家分享一下GitHub的一些使用技巧,帮助你 ...

  3. Jpa 自定义@Query查询总结

    第一种方式 能够请求,,返回数据为 不带字段 第二种方式   报错 第三种方式 正确 总结:如果返回 List<TbRegionDO> 不能 有as存在 ,,只能查询所有 select s ...

  4. JavaScript ajax返回状态

    该内容转自CSDN:http://blog.csdn.net/u013381651/article/details/51261956 xmlhttp.readyState的值及解释: 0:请求未初始化 ...

  5. 线程池提交任务的两种方式:execute与submit的区别

    Java中的线程池在进行任务提交时,有两种方式:execute和submit方法. 一.execute和submit的区别 execute只能提交Runnable类型的任务,无返回值.submit既可 ...

  6. ACL 权限控制机制 ?

    UGO(User/Group/Others) 目前在 Linux/Unix 文件系统中使用,也是使用最广泛的权限控制方式.是一种粗 粒度的文件系统权限控制模式. ACL(Access Control ...

  7. Eureka server

    Eureka server使用的不是spring mvc的框架,而是使用Jersey. Eureka server ,启动的流程,追本溯源,是在 DiscoveryClient里面,使用这个构造方法 ...

  8. Netty学习摘记 —— 再谈引导

    本文参考 本篇文章是对<Netty In Action>一书第八章"引导"的学习摘记,主要内容为引导客户端和服务端.从channel内引导客户端.添加ChannelHa ...

  9. DASCTF Oct吉林工师web

    迷路的魔法少女 进入环境给出源码 <?php highlight_file('index.php'); extract($_GET); error_reporting(0); function ...

  10. EDM响应式邮件框架:MJML

    概述 新课题研究:响应式邮件框架MJML(MJML官网:https://mjml.io/)姐妹篇: EDM响应式邮件框架:Formerly Ink 介绍 MJML是一种标记语言,设计用于轻松实现一个响 ...