BZOJ 3173 Tjoi2013 最长上升子序列 Treap+树状数组

题目大意:给定一个序列,依次将1~n插入,问每次插入之后序列的LIS长度是多少

由于是从小到大插入,因此插入一个数之后显然是不影响之前的答案的

因此我们不妨先用平衡树搞出插入之后的序列,再求一遍LIS即可

注意最后每个点还要对前面的取一下max 因为插入后LIS可能还是之前的序列

蒟蒻的我到底还是把平衡树写挂了。。。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
int n,a[M],ans[M];
namespace Treap{
	struct abcd{
		abcd *ls,*rs;
		int val,key,size;
		abcd(int x);
		void Maintain();
	}*null=new abcd(0),*root=null;
	abcd :: abcd(int x)
	{
		ls=rs=null;
		val=x;
		key=rand()*(bool)x;
		size=(bool)x;
	}
	void abcd :: Maintain()
	{
		size=ls->size+rs->size+1;
	}
	void Zig(abcd *&x)
	{
		abcd *y=x->ls;
		x->ls=y->rs;
		y->rs=x;
		x=y;
		x->rs->Maintain();
	}
	void Zag(abcd *&x)
	{
		abcd *y=x->rs;
		x->rs=y->ls;
		y->ls=x;
		x=y;
		x->ls->Maintain();
	}
	void Insert(abcd *&x,int y,int z)
	{
		if(x==null)
		{
			x=new abcd(z);
			return ;
		}
		if(y<=x->ls->size)
		{
			Insert(x->ls,y,z);
			if(x->ls->key>x->key)
				Zig(x);
		}
		else
		{
			Insert(x->rs,y-x->ls->size-1,z);
			if(x->rs->key>x->key)
				Zag(x);
		}
		x->Maintain();
	}
	void Output(abcd *x)
	{
		static int cnt;
		if(x==null)
			return ;
		Output(x->ls);
		a[++cnt]=x->val;
		Output(x->rs);
	}
}
namespace BIT{
	int c[M];
	void Update(int x,int y)
	{
		for(;x<=n;x+=x&-x)
			c[x]=max(c[x],y);
	}
	int Get_Ans(int x)
	{
		int re=0;
		for(;x;x-=x&-x)
			re=max(re,c[x]);
		return re;
	}
}
int main()
{
	using namespace Treap;
	using namespace BIT;
	int i,x;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&x);
		Insert(root,x,i);
	}
	Output(root);
	for(i=1;i<=n;i++)
	{
		int temp=Get_Ans(a[i])+1;
		Update(a[i],temp);
		ans[a[i]]=temp;
	}
	for(i=1;i<=n;i++)
		ans[i]=max(ans[i],ans[i-1]);
	for(i=1;i<=n;i++)
		printf("%d\n",ans[i]);
	return 0;
}
时间: 2024-10-18 03:10:52

BZOJ 3173 Tjoi2013 最长上升子序列 Treap+树状数组的相关文章

BZOJ 3173 [Tjoi2013]最长上升子序列 Treap+LIS

题意:链接 方法: Treap+LIS 解析: 刚看到题还蒙了一会,无从下手啊- -! 后来寻思找找规律. 画画样例以及瞎编了两组数据之后发现点问题- 答案递增? 然后才反应过来- -,当我们从小到大插入的时候,插入后的情况是不影响插入前的. 所以这样的话我们可以把整个序列先弄出来? 之后求一个LIS,这时候对于每一个数来说,他都有个LIS值,当然这个可能不是他插入之后的最优解,因为之前的值可能比他插入之后还要大. 所以我们再需要扫一下数组,更新下答案即可. 至于第一部分找序列,用treap实现

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

3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1613  Solved: 839[Submit][Status][Discuss] Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input 第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字Xk

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

3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1524  Solved: 797[Submit][Status][Discuss] Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input 第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字Xk

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

因为是从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))

bzoj 3173: [Tjoi2013]最长上升子序列(splay)

3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1315  Solved: 682 [Submit][Status][Discuss] Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input 第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字

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

这个题感觉比较简单,但却比较容易想残.. 我不会用树状数组求这个原排列,于是我只好用线段树...毕竟 Gromah 果弱马. 我们可以直接依次求出原排列的元素,每次找到最小并且最靠右的那个元素,假设这是第 $i$ 次找的,那么这就是原排列的第 $i$ 项,然后我们就把这个元素删去(变成很大的数),再把这个数以左的数都加 1,进行下一轮. 然后就是裸的最长上升子序列啦~~~ 时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$. 1 #include <cstdio> 2 #inclu

[bzoj2124]等差子序列(hash+树状数组)

我又来更博啦 2124: 等差子序列 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 941  Solved: 348[Submit][Status][Discuss] Description 给一个1到N的排列{Ai},询问是否存在1<=p1=3),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列. Input 输入的第一行包含一个整数T,表示组数.下接T组数据,每组第一行一个整数N,每组第二行为一个1到N的排列,数字两两之间用空格隔开. O

[CDQ分治][Treap][树状数组]Theresa与数据结构

Description 这是个复杂的世界.人类社会,自然界,还有地球之外的银河--每一天日出日落,人来人往,步履匆匆.究竟是为什么呢?那支配着一切的至高无上的法则又是否存在呢?Theresa知道,这个问题并不是一朝一夕就可以解答的,只有在仔细.深入的观察和思考以后,才有可能将所有支离破碎的线索联系起来,从而隐约窥见真实的答案.于是,Theresa经常思考生活中遇到的大大小小的问题.为什么港台出版的书籍里印刷的汉字她一个也不认识呢?为什么隔夜的白开水中富含一氧化二氢呢?为什么每年都有一段时间Gma

BZOJ3173: [Tjoi2013]最长上升子序列 Treap 平衡树

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 Outp