博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj3173[Tjoi2013]最长上升子序列 平衡树+lis
阅读量:5240 次
发布时间:2019-06-14

本文共 1557 字,大约阅读时间需要 5 分钟。

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

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 2253  Solved: 1136
[ ][ ][ ]

Description

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

Input

第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字Xk,表示我们将k插入到位置Xk(0<=Xk<=k-1,1<=k<=N)

Output

N行,第i行表示i插入Xi位置后序列的最长上升子序列的长度是多少。

Sample Input

3

0 0 2

Sample Output

1

1
2

HINT

100%的数据 n<=100000

 

用平衡树构造序列后,对整个序列求一个lis 

设f[i]表示i结尾的lis 可以确定这样的lis一定是插入i后的答案(因为之前的都比i小)
输出答案的时候取前缀max

#include
#include
#include
#include
#define ll long long#define N 100050using namespace std;int n,rt,cnt,num,a[N],b[N],ans[N],ls[N],siz[N],rd[N],rs[N];void update(int u){siz[u]=siz[ls[u]]+siz[rs[u]]+1;}void lturn(int &u){ int t=rs[u];rs[u]=ls[t];ls[t]=u; update(u);update(t);u=t;}void rturn(int &u){ int t=ls[u];ls[u]=rs[t];rs[t]=u; update(u);update(t);u=t;}void insert(int &u,int k){ if(!u){ u=++cnt;siz[u]=1; rd[u]=rand(); return; } siz[u]++; if(siz[ls[u]]
tot){ b[++tot]=a[i]; ans[a[i]]=tot; } else{ ans[a[i]]=p; b[p]=a[i]; } }}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int p; scanf("%d",&p); insert(rt,p); } dfs(rt);solve(); //for(int i=1;i<=n;i++)printf("%d ",a[i]); for(int i=1;i<=n;i++){ ans[i]=max(ans[i],ans[i-1]); printf("%d\n",ans[i]); } return 0;}

转载于:https://www.cnblogs.com/wsy01/p/8079727.html

你可能感兴趣的文章
RabbitMQ、Redis、Memcache、SQLAlchemy
查看>>
知识不是来炫耀的,而是来分享的-----现在的人们却…似乎开始变味了…
查看>>
口胡:[HNOI2011]数学作业
查看>>
03 线程池
查看>>
手机验证码执行流程
查看>>
设计模式课程 设计模式精讲 2-2 UML类图讲解
查看>>
Silverlight 的菜单控件。(不是 Toolkit的)
查看>>
jquery的contains方法
查看>>
linux后台运行和关闭SSH运行,查看后台任务
查看>>
桥接模式-Bridge(Java实现)
查看>>
303. Range Sum Query - Immutable
查看>>
图片加载失败显示默认图片占位符
查看>>
【★】浅谈计算机与随机数
查看>>
解决 sublime text3 运行python文件无法input的问题
查看>>
javascript面相对象编程,封装与继承
查看>>
算法之搜索篇
查看>>
新的开始
查看>>
Leetcode 226: Invert Binary Tree
查看>>
解决miner.start() 返回null
查看>>
bzoj 2007: [Noi2010]海拔【最小割+dijskstra】
查看>>