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

--------------------------------------------------------------------

#include<bits/stdc++.h>
 
#define rep(i, n) for(int i = 0; i < n; ++i)
#define clr(x, c) memset(x, c, sizeof(x))
#define foreach(i, x) for(__typeof(x.begin()) i = x.begin(); i != x.end(); i++)
 
using namespace std;
 
const int maxn = 100009;
 
struct Node {
Node *ch[2], *p;
int s, v;
inline void upd() {
s = ch[0]->s + ch[1]->s + 1;
}
inline void setc(Node* t, int d) {
ch[d] = t;
t->p =this;
}
inline bool d() {
return this == p->ch[1];
}
} pool[maxn], *pt = pool, *root, *null;
 
Node* newNode(int _ = 0) {
pt->v = _; pt->s = 1;
pt->ch[0] = pt->ch[1] = pt->p = null;
return pt++;
}
 
void rot(Node* t) {
Node* p = t->p;
int d = t->d();
p->p->setc(t, p->d());
p->setc(t->ch[d ^ 1], d);
t->setc(p, d ^ 1);
p->upd();
if(p == root) root = t;
}
  
void splay(Node* t, Node* f = null) {
while(t->p != f) {
if(t->p->p != f)
   t->d() != t->p->d() ? rot(t) : rot(t->p);
rot(t);
}
t->upd();
}
 
Node* select(int k) {
for(Node* t = root; ;) {
int s = t->ch[0]->s;
if(k == s) return t;
if(k > s)
   k -= s + 1, t = t->ch[1];
else
   t = t->ch[0];
}
}
 
void init() {
null = newNode();
null->ch[0] = null->ch[1] = null->p = null;
null->s = 0;
root = newNode(maxn);
root->setc(newNode(-maxn), 0);
root->upd();
}
 
int seq[maxn], N = 0, g[maxn], dp[maxn];
 
void dfs(Node* t) {
if(t == null) return;
dfs(t->ch[0]);
if(t->v != maxn && t->v != -maxn) seq[N++] = t->v;
dfs(t->ch[1]);
}
 
int main() {
freopen("test.in", "r", stdin);
init();
int n;
cin >> n;
rep(i, n) {
int v;
scanf("%d", &v);
Node *L = select(v), *R = select(v + 1);
splay(L); splay(R, L);
R->setc(newNode(i), 0);
R->upd(); L->upd();
   g[i] = maxn;
}
dfs(root);
rep(i, n) {
int p = lower_bound(g, g + n, seq[i]) - g;
dp[seq[i]] = p + 1;
g[p] = seq[i];
}
int ans = 0;
rep(i, n) {
   ans = max(ans, dp[i]);
printf("%d\n", ans);
}
return 0;
}

--------------------------------------------------------------------

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

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 806  Solved: 432
[Submit][Status][Discuss]

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

Source

BZOJ 3173: [Tjoi2013]最长上升子序列( BST + LIS )的更多相关文章

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

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

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

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

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

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

  4. bzoj 3173 [Tjoi2013]最长上升子序列 (treap模拟+lis)

    [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2213  Solved: 1119[Submit][Status] ...

  5. BZOJ 3173 [Tjoi2013] 最长上升子序列 解题报告

    这个题感觉比较简单,但却比较容易想残.. 我不会用树状数组求这个原排列,于是我只好用线段树...毕竟 Gromah 果弱马. 我们可以直接依次求出原排列的元素,每次找到最小并且最靠右的那个元素,假设这 ...

  6. BZOJ 3173: [Tjoi2013]最长上升子序列 (线段树+BIT)

    先用线段树预处理出每个数最终的位置.然后用BIT维护最长上升子序列就行了. 用线段树O(nlogn)O(nlogn)O(nlogn)预处理就直接倒着做,每次删去对应位置的数.具体看代码 CODE #i ...

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

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

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

    一眼切~ 重点是按照 $1$~$n$ 的顺序插入每一个数,这样的话就简单了. #include <cstdio> #include <algorithm> #define N ...

  9. bzoj3173[Tjoi2013]最长上升子序列 平衡树+lis

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2253  Solved: 1136[Submit][S ...

随机推荐

  1. div+css 布局下兼容IE6 IE7 FF常见问题

    div+css 布局下兼容IE6 IE7 FF常见问题 收藏 所有浏览器 通用 (市面上主要用到的IE6 IE7 FF)height: 100px; IE6 专用 _height: 100px; IE ...

  2. Mac上使用Visual Studio Code开发/调试.NET Core代码

    Mac上使用Visual Studio Code开发/调试.NET Core代码 .Net Core 1.0终于发布了,Core的一大卖点就是跨平台.这个跨平台不只是跨平台运行,而且可以跨平台开发.今 ...

  3. 部署一个class文件

    只发布一个class文件找到项目工作空间/target/class..根据项目结构找到修改的java文件编译的class文件比如RegexUtils.class使用SecureFXPortable将文 ...

  4. HDU2084:数塔(DP)

    Problem Description 在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的: 有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大 ...

  5. (3)选择元素——(3)$()方法(The $() function)

    No matter which type of selector we want to use in jQuery, we always start with the same function: $ ...

  6. Android 进程和线程

    进程和线程 如果某个应用程序组件是第一次被启动,且这时应用程序也没有其他组件在运行,则Android系统会为应用程序创建一个包含单个线程的linux进程.默认情况下,同一个应用程序的所有组件都运行在同 ...

  7. AFNetworking 进行网络监测

    AFNetworking 进行网络监测 引入头文件,创建检测判断BOOL值 // 网络请求的头文件 #import <AFNetworking.h> @interface ViewCont ...

  8. C#中的DataTable简单使用Merge

    //不同结构的DataTable追加第二个DataTable数据在对应行后的 简单使用//不同结构的DataTable追加在行后面的合并 DataTable dt = new DataTable(); ...

  9. js面向对象继承

    前言 最近看到js面向对象这章节了,主要学习了原型和面向对象继承关系,为了梳理自己的知识逻辑,特此记录. js的面向对象 先说说我目前了解的js创建对象方法 1.写一个函数,然后通过new创建对象 2 ...

  10. Sprintf()的思考和引出的相关问题

    Sprintf()为什么不安全? 功能 把格式化的数据写入某个 字符串 缓冲区. 头文件 stdio.h 原型 int sprintf( char *buffer, const char *forma ...