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

來源:互聯網
上載者:User

標籤:

題意:連結方法: Treap+LIS解析:剛看到題還蒙了一會,無從下手啊- -!後來尋思找找規律。畫畫範例以及瞎編了兩組資料之後發現點問題…答案遞增?然後才反應過來- -,當我們從小到大插入的時候,插入後的情況是不影響插入前的。所以這樣的話我們可以把整個序列先弄出來?之後求一個LIS,這時候對於每一個數來說,他都有個LIS值,當然這個可能不是他插入之後的最優解,因為之前的值可能比他插入之後還要大。所以我們再需要掃一下數組,更新下答案即可。至於第一部分找序列,用treap實現是很優越的。第二部分呢?n^2的做法顯然這裡是過不了的,所以nlogn就好。大複雜度O(nlogn)代碼:
#include <ctime>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define N 100010using namespace std;int size,n,root;struct node{    int l,r,rnd,siz,w,v;}tr[N];void pushup(int rt){    tr[rt].siz=tr[tr[rt].l].siz+tr[tr[rt].r].siz+1; }void lturn(int &rt){    int t=tr[rt].r;    tr[rt].r=tr[t].l;    tr[t].l=rt;    tr[t].siz=tr[rt].siz;    pushup(rt);    rt=t;}void rturn(int &rt){    int t=tr[rt].l;    tr[rt].l=tr[t].r;    tr[t].r=rt;    tr[t].siz=tr[rt].siz;    pushup(rt);    rt=t;}void insert(int &rt,int v){    if(!rt)    {        rt=++size;        tr[rt].l=tr[rt].r=0,tr[rt].siz=1;        tr[rt].v=size,tr[rt].rnd=rand();        return;     }    tr[rt].siz++;    if(v<=tr[tr[rt].l].siz+1)    {        insert(tr[rt].l,v);        if(tr[tr[rt].l].rnd<tr[rt].rnd)rturn(rt);    }else    {        insert(tr[rt].r,v-tr[tr[rt].l].siz-1);        if(tr[tr[rt].r].rnd<tr[rt].rnd)lturn(rt);    }}int tot;int seq[N];void getseq(int rt){    if(tr[rt].l!=0)        getseq(tr[rt].l);    seq[++tot]=tr[rt].v;    if(tr[rt].r!=0)        getseq(tr[rt].r);}int f[N],d[N],ans[N];int print[N]; void getlis(){    memset(d,0x3f,sizeof(d));    d[0]=0;    d[1]=seq[1],f[1]=1;    int mx=1;    for(int i=2;i<=n;i++)    {        if(seq[i]>d[mx])        {            f[i]=++mx;            d[mx]=min(d[mx],seq[i]);        }else        {            int l=0,r=mx,ans=0;            while(l<=r)            {                int mid=(l+r)>>1;                if(d[mid]<seq[i])ans=mid,l=mid+1;                else r=mid-1;            }            f[i]=ans+1;            d[ans+1]=min(d[ans+1],seq[i]);        }    }}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        int x;        scanf("%d",&x);x++;        insert(root,x);    }    getseq(root);    getlis();    for(int i=1;i<=n;i++)print[seq[i]]=f[i];    for(int i=1;i<=n;i++)print[i]=max(print[i],print[i-1]);    for(int i=1;i<=n;i++)printf("%d\n",print[i]);}

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.