zoukankan      html  css  js  c++  java
  • [BZOJ]3173: [Tjoi2013]最长上升子序列

     题解:   考虑按照元素升序加入  所以对位置在其后的元素LIS无影响 然后从前面位置的最大值转移过来就行 ,,,,平衡树无脑模拟

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=3e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    int key[MAXN],maxx[MAXN],pre[MAXN],ch[MAXN][2],sz[MAXN];
    int rt,n;
    
    void newnode(int x,int t){
        key[x]=maxx[x]=t;pre[x]=ch[x][0]=ch[x][1]=0;sz[x]=1;
    }
    
    void up(int x){
        sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
        maxx[x]=max(key[x],max(maxx[ch[x][0]],maxx[ch[x][1]]));
    }
    
    void rotate(int x,int kind){
        int y=pre[x];
        ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y;
        if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
        up(y);
    }
    
    void splay(int x,int goal){
        while(pre[x]!=goal){
        if(pre[pre[x]]==goal)rotate(x,ch[pre[x]][0]==x);
        else{
            int y=pre[x];int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x)rotate(x,!kind),rotate(x,kind);
            else rotate(y,kind),rotate(x,kind);
        }
        }
        if(goal==0)rt=x;
        up(x);
    }
    
    int find1(int x,int k){
        if(k==sz[ch[x][0]]+1)return x;
        else if(k<=sz[ch[x][0]])return find1(ch[x][0],k);
        else return find1(ch[x][1],k-sz[ch[x][0]]-1);
    }
    
    void inte(){
        newnode(n+1,0);newnode(n+2,0);
        rt=n+1;ch[rt][1]=n+2;pre[n+2]=rt;up(rt);
    }
    
    int query(int id,int x){
        //cout<<find1(rt,x)<<endl;
        splay(find1(rt,x),0);splay(find1(rt,x+1),rt);
        int t=max(maxx[ch[rt][0]],key[rt]);t=max(t+1,1);
        newnode(id,t);pre[id]=ch[rt][1];ch[ch[rt][1]][0]=id;
        up(ch[rt][1]);up(rt);
        return maxx[rt];
    }
    
    int main(){
        n=read();
        inte();
        inc(i,1,n){
        int t=read();
        printf("%d
    ",query(i,t+1));
        }
        return 0;
    }
    

      

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

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2770  Solved: 1398
    [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

  • 相关阅读:
    Linux 基础篇(二)
    Linux 基础篇
    pandas 的使用
    git 使用和一些错误
    NetBackup :Unable to retrieve version of the server xxx.xxx.xxx
    Splunk 基本使用
    Symantec(赛门铁克)非受管检测
    matplotlib 的几种柱状图
    python 清空list的几种方法
    ACE
  • 原文地址:https://www.cnblogs.com/wang9897/p/10363749.html
Copyright © 2011-2022 走看看