zoukankan      html  css  js  c++  java
  • 【bzoj3173】[Tjoi2013]最长上升子序列 Treap

    题目描述

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

    输入

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

    输出

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

    样例输入

    3
    0 0 2

    样例输出

    1
    1
    2


    题解

    Treap

    考虑到数据是从小到大插入的,所以每次插入后这个数只会对自身有影响,并不会对前后有影响;而且自身的答案只受其前边位置的答案的影响。

    具体地说,设f[i]表示最后一个数为i的最长上升子序列长度,那么插入时f[i]=max{f[j]}+1(pos(j)<pos(i))。

    查询时查询的是整个f数组的最大值。

    这样就需要一个数据结构,支持插入一个数、查询以1开头的区间的最大值,可以使用Treap搞定。

    这里的insert函数与普通的不同,是指定位置的插入,所以判断时比较的是子树大小。

    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #define N 100010
    using namespace std;
    int f[N] , l[N] , r[N] , si[N] , rnd[N] , maxn[N] , root , tot;
    void pushup(int k)
    {
    	si[k] = si[l[k]] + si[r[k]] + 1 , maxn[k] = max(f[k] , max(maxn[l[k]] , maxn[r[k]]));
    }
    void zig(int &k)
    {
    	int t = l[k];
    	l[k] = r[t] , r[t] = k , si[t] = si[k] , pushup(k) , k = t;
    }
    void zag(int &k)
    {
    	int t = r[k];
    	r[k] = l[t] , l[t] = k , si[t] = si[k] , pushup(k) , k = t;
    }
    void ins(int &k , int x , int w)
    {
    	if(!k) k = ++tot , f[k] = w , rnd[k] = rand();
    	else if(x <= si[l[k]])
    	{
    		ins(l[k] , x , w);
    		if(rnd[l[k]] < rnd[k]) zig(k);
    	}
    	else
    	{
    		ins(r[k] , x - si[l[k]] - 1 , w);
    		if(rnd[r[k]] < rnd[k]) zag(k);
    	}
    	pushup(k);
    }
    int query(int k , int x)
    {
    	if(!k) return 0;
    	if(x <= si[l[k]]) return query(l[k] , x);
    	return max(max(maxn[l[k]] , f[k]) , query(r[k] , x - si[l[k]] - 1));
    }
    int main()
    {
    	int n , x;
    	scanf("%d" , &n);
    	while(n -- ) scanf("%d" , &x) , ins(root , x , query(root , x) + 1) , printf("%d
    " , maxn[root]);
    	return 0;
    }

     

  • 相关阅读:
    记一次模型调试问题:使用TextLSTM/RNN学习不动,损失和acc均无变化
    机器学习常用损失函数
    java多线程使用mdc追踪日志
    搜索笔记整理
    pytorch加载bert模型报错
    Transformer源代码解释之PyTorch篇
    matplotlib画图并设置风格
    PyTorch实现断点继续训练
    通过sklearn使用tf-idf提取英文关键词
    通过依存关系生成邻接矩阵
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6856502.html
Copyright © 2011-2022 走看看