【BZOJ】3173: [Tjoi2013]最長上升子序列(樹狀數組)

來源:互聯網
上載者:User

標籤:log   pac   sed   etc   數組   splay   題解   注意   十分   

【題意】給定ai,將1~n從小到大插入到第ai個數字之後,求每次插入後的LIS長度。

【演算法】樹狀數組||平衡樹

【題解】

這是樹狀數組的一個用法:O(n log n)尋找首碼和為k的最小位置。(當數列中只有0和1時,轉化為求對應排名的數字,就是簡單代替平衡樹)

根據樹狀數組的二進位分組規律,從大到小進行倍增,可以發現每次需要加的Σa[i],i∈(now,now+(1<<i)]剛好就是c[now+(1<<i)]。

文字表述就是,跳躍到的位置的c[]剛好表示中間跳躍的數字和,這是樹狀數組二進位分組規律的特殊性質。

還需要注意的是,實際上需要尋找首碼和<k的最大位置,最後+1。(否則會被目標數字後面的0幹擾)

 

利用上述的方法,初始樹狀數組全部置為1,然後從n到1倒著尋找並刪除,就可以得到每個數字在最終序列中的位置。

這道題由於從小到大插入,可以發現將所有數字全部插入也不會破壞過程中需要的LIS(只會在最後增長)。

那麼第i個答案就是以數字1~i結尾的LIS的最長長度。

所以令f[i]表示最終序列中以數字 i 結尾的LIS,則第i個答案就是min(f[j]),j=1~i。(是數字i,不是第i個位置)

求解f[i]只需在O(n log n)求解整個最終序列的LIS的過程中求出即可。

總複雜度O(n log n)。

#include<cstdio>#include<cstring>#include<algorithm>#include<cctype>#define lowbit(x) (x&-x)using namespace std;const int maxn=100010;int a[maxn],b[maxn],c[maxn],g[maxn],anss[maxn],n;int read(){    char c;int s=0,t=1;    while(!isdigit(c=getchar()))if(c==‘-‘)t=-1;    do{s=s*10+c-‘0‘;}while(isdigit(c=getchar()));    return s*t;}void insert(int x,int k){for(int i=x;i<=n;i+=lowbit(i))c[i]+=k;}int find(int x){    int now=0,ans=0;    for(int i=20;i>=0;i--){        now+=(1<<i);        if(now<n&&ans+c[now]<x)ans+=c[now];//< near        else now-=(1<<i);    }    now++;    insert(now,-1);    return now;}int max(int a,int b){return a<b?b:a;}int main(){    n=read();    for(int i=1;i<=n;i++){        a[i]=read();        c[i]++;c[i+lowbit(i)]+=c[i];    }    for(int i=n;i>=1;i--)b[find(a[i]+1)]=i;    int m=0;    for(int i=1;i<=n;i++){        int s=lower_bound(g+1,g+m+1,b[i])-g;        if(s>m)g[++m]=b[i];else g[s]=b[i];        anss[b[i]]=s;    }    for(int i=1;i<=n;i++){        anss[i]=max(anss[i-1],anss[i]);        printf("%d\n",anss[i]);    }    return 0;}
View Code

 

最後,代碼中運用的線性構造樹狀數組,原理十分簡單。

首先要求1~n都有數字(0也行),然後每個數加到自身c[i]+=a[i],再貢獻一下父親c[i+lowbit(i)]+=c[i]就可以了。

【BZOJ】3173: [Tjoi2013]最長上升子序列(樹狀數組)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.