这题用fhqtreap可以在线。

  fhqtreap上维护以i结尾的最长上升子序列,数字按从小到大加入, 因为前面的数与新加入的数无关, 后面的数比新加入的数小, 所以新加入的数对原序列其他数的值没有影响。

  然后就可以直接fhqtreap模拟啦

  忘记所有答案取max WA了半天T T

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define lt tree[x].ls
#define rt tree[x].rs
using namespace std;
const int maxn=, seed=, inf=1e9+;
struct treap{int sum, mx, rnd, size, ls, rs;}tree[maxn];
int n, x, tott, root, ans;
void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline void build(int &x)
{
tree[x=++tott].rnd=rand()<<|rand();
tree[x].sum=tree[x].mx=tree[x].size=;
}
inline int max(int a, int b){return a>b?a:b;}
inline void up(int x)
{
if(!x) return;
tree[x].size=tree[lt].size+tree[rt].size+;
tree[x].mx=max(tree[x].sum, max(tree[lt].mx, tree[rt].mx));
}
void split(int x, int &l, int &r, int k)
{
if(!k) l=, r=x;
else if(k==tree[x].size) l=x, r=;
else if(k<=tree[lt].size) r=x, split(lt, l, lt, k), up(x);
else l=x, split(rt, rt, r, k-tree[lt].size-), up(x);
}
void merge(int &x, int l, int r)
{
if(!l || !r) x=l+r;
else if(tree[l].rnd<tree[r].rnd) x=l, merge(rt, rt, r), up(x);
else x=r, merge(lt, l, lt), up(x);
}
inline int solve(int pos)
{
int x, y, tmp;
build(tmp); split(root, x, y, pos);
tree[tmp].sum=tree[tmp].mx=max(, tree[x].mx)+;
merge(x, x, tmp); merge(root, x, y);
return ans=max(ans, tree[tmp].sum);
}
int main()
{
srand(seed); read(n); tree[].mx=-inf; tree[].rnd=inf;
for(int i=;i<=n;i++) read(x), printf("%d\n", solve(x));
}

  貌似还可以用BIT, 过会再补

  先把所有数设成1,1表示<=x的数,0表示>x的数,然后从n到1扫一遍,对于每个要求的位置pos,就是找到前缀为pos的位置插入,至于怎么找到前缀为pos的位置,就用BIT求第k大的方法就好了。

  求出原序列之后, 求每一个数结尾的LIS就好了

  注意:BIT求第k大的时候add是单点修改

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
const int maxn=;
int n, mx, ans, x;
int tree1[maxn], tree2[maxn], pos[maxn], p[maxn], f[maxn];
void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline int max(int a, int b){return a>b?a:b;}
inline void add1(int x, int delta){for(;x<=mx;x+=x&-x) tree1[x]+=delta;}
inline void add2(int x, int delta){for(;x<=n;x+=x&-x) tree2[x]=max(tree2[x], delta);}
inline int query2(int x){int sum=; for(;x;x-=x&-x) sum=max(sum, tree2[x]); return sum;}
int main()
{
read(n);
for(mx=;mx<n;mx<<=);
for(int i=;i<=mx;i++)
tree1[i]+=(i<=n), i+(i&-i)<=mx&&(tree1[i+(i&-i)]+=tree1[i]);
for(int i=;i<=n;i++) read(p[i]), p[i]++;
for(int i=n;i;i--)
{
int l=, r=mx, k=;
while(l<r)
{
int mid=(l+r)>>;
k+=tree1[mid];
if(k<p[i]) l=mid+;
else k-=tree1[mid], r=mid;
}
pos[l]=i;
add1(l, -);
}
for(int i=, tmp;i<=n;i++)
f[pos[i]]=query2(pos[i]-)+, add2(pos[i], f[pos[i]]);
for(int i=;i<=n;i++) ans=max(ans, f[i]), printf("%d\n", ans);
}

bzoj3173: [Tjoi2013]最长上升子序列(fhqtreap)的更多相关文章

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

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

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

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

  3. bzoj3173: [Tjoi2013]最长上升子序列(树状数组+二分倒推)

    3173: [Tjoi2013]最长上升子序列 题目:传送门 题解:  好题! 怎么说吧...是应该扇死自己...看错了两次题: 每次加一个数的时候,如果当前位置有数了,是要加到那个数的前面,而不是直 ...

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

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

  5. bzoj千题计划316:bzoj3173: [Tjoi2013]最长上升子序列(二分+树状数组)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3173 插入的数是以递增的顺序插入的 这说明如果倒过来考虑,那么从最后一个插入的开始删除,不会对以某 ...

  6. BZOJ3173:[TJOI2013]最长上升子序列(Splay)

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

  7. BZOJ3173 TJOI2013最长上升子序列(splay)

    容易发现如果求出最后的序列,只要算一下LIS就好了.序列用平衡树随便搞一下,这里种一棵splay. #include<iostream> #include<cstdio> #i ...

  8. 【LG4309】【BZOJ3173】[TJOI2013]最长上升子序列

    [LG4309][BZOJ3173][TJOI2013]最长上升子序列 题面 洛谷 BZOJ 题解 插入操作显然用平衡树就行了 然后因为后面的插入对前面的操作无影响 就直接在插入完的序列上用树状数组求 ...

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

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

随机推荐

  1. 使用Python的Requests库进行web接口测试

    1.Requests简介Requests 是使用 Apache2 Licensed 许可证的 HTTP 库.用 Python 编写,真正的为人类着想. Python 标准库中的 urllib2 模块提 ...

  2. 用gdb调试程序(Linux环境)

    一般来说,GDB主要帮忙你完成下面四个方面的功能: 1.启动你的程序,可以按照你的自定义的要求随心所欲的运行程序.    2.可让被调试的程序在你所指定的调置的断点处停住.(断点可以是条件表达式)   ...

  3. Dsniff简介

    原文发表于:2010-09-25 转载至cu于:2012-07-21 前两天因为看局域网安全的视频中介绍dsniff,也想自己安装下来看看效果.简单的使用没什么难的(高级使用就需要研究文档了),但是安 ...

  4. NO.3:自学python之路------集合、文件操作、函数

    引言 本来计划每周完成一篇Python的自学博客,由于上一篇到这一篇遇到了过年.开学等杂事,导致托更到现在.现在又是一个新的学期,春天也越来越近了(冷到感冒).好了,闲话就说这么多.开始本周的自学Py ...

  5. react-native debug js remotely跨域问题

    react-native debug js remotely跨域问题 我们在安卓真机上调试react-native时,启用debug js remotely的时候,会出现跨域问题.这个时候我们只需要一 ...

  6. Scrum立会报告+燃尽图(Beta阶段第二周第七次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2415 项目地址:https://coding.net/u/wuyy694 ...

  7. OpenCV学习笔记——imread、imwrite以及imshow

    1.imread Loads an image from a file. 从文件中读取图像. C++: Mat imread(const string& filename, int flags ...

  8. tomcat配置服务

    1.在server中右键添加tomcat 2.双击tomcat打开配置窗口添加jvm参数 -Doapath="C:\exeye-workspace\exEyeWeb\oadoc"  ...

  9. 蜗牛慢慢爬 LeetCode 1.Two Sum [Difficulty: Easy]

    题目 Given an array of integers, return indices of the two numbers such that they add up to a specific ...

  10. 如何让TEdit在获取输入焦点后selectAll?

    关于网友提出的“ 如何让TEdit在获取输入焦点后selectAll?”问题疑问,本网通过在网上对“ 如何让TEdit在获取输入焦点后selectAll?”有关的相关答案进行了整理,供用户进行参考,详 ...