日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bzoj 3173 最长上升子序列

發布時間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bzoj 3173 最长上升子序列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Written with StackEdit.

Description

給定一個序列,初始為空。現在我們將\(1\)\(N\)的數字插入到序列中,每次將一個數字插入到一個特定的位置。每插入一個數字,我們都想知道此時最長上升子序列長度是多少?

Input

第一行一個整數\(N\),表示我們要將\(1\)\(N\)插入序列中,接下是\(N\)個數字,第\(k\)個數字\(X_k\),表示我們將\(k\)插入到位置\(X_k(0\leq X_k\leq k-1,1\leq k\leq N)\),

Output

\(N\)行,第\(i\)行表示\(i\)插入\(X_i\)位置后序列的最長上升子序列的長度是多少。

Sample Input

3
0 0 2

Sample Output

1
1
2

HINT

\(100\%\)的數據 \(n\leq100000\).

Solution

  • 如果我們已經得到了最后的序列,我們可以用\(O(nlogn)\)的算法計算出\(LIS\),同時維護\(ans[i]\),表示以\(i\)作為結尾的上升子序列的最大長度.
  • 再令\(g[i]\)表示最終要輸出的答案,即插入\(i\)后的\(LIS\)長度.
  • 因為整個序列是從小到大插入的,所以\(g[i]=max_{j=1}^{i}ans[j].\)
  • 使用前綴和優化一下即可.
  • 維護元素的插入可以寫一顆平衡樹.
#include<bits/stdc++.h> using namespace std; typedef long long LoveLive; inline int read() {int out=0,fh=1;char jp=getchar();while ((jp>'9'||jp<'0')&&jp!='-')jp=getchar();if (jp=='-'){fh=-1;jp=getchar();}while (jp>='0'&&jp<='9'){out=out*10+jp-'0';jp=getchar();}return out*fh; } const int MAXN=1e5+10; int a[MAXN],qlen=0; int n; struct FhqTreap {int x,y;struct node{int lson,rson,siz,weight,key;} treap[MAXN];int idx,root;FhqTreap(){x=0,y=0;idx=0;root=0;treap[0].key=0;treap[0].lson=treap[0].rson=0;treap[0].weight=0;treap[0].siz=0;}#define rt treap[o]#define ls treap[treap[o].lson]#define rs treap[treap[o].rson]inline int newnode(int key){int o=++idx;rt.lson=rt.rson=0;rt.siz=1;rt.weight=rand();rt.key=key;return o;}inline void pushup(int o){rt.siz=ls.siz+rs.siz+1;}int merge(int x,int y){if(!x || !y)return x+y;if(treap[x].weight<treap[y].weight){treap[x].rson=merge(treap[x].rson,y);pushup(x);return x;}else{treap[y].lson=merge(x,treap[y].lson);pushup(y);return y;}}void split(int &x,int &y,int k,int o){if(!o)x=y=0;else{if(k<=ls.siz){y=o;split(x,rt.lson,k,rt.lson);}else{x=o;split(rt.rson,y,k-ls.siz-1,rt.rson);}pushup(o);}}void ins(int key,int pos){split(x,y,pos,root);y=merge(newnode(key),y);root=merge(x,y);}void dfs(int o){if(!o)return;dfs(rt.lson);a[++qlen]=rt.key;dfs(rt.rson);}void getseq(){dfs(root);} }T; #define inf 0x7fffffff int f[MAXN],ans[MAXN]; int main() {srand(19260817);n=read();for(int i=1;i<=n;++i){int pos=read();T.ins(i,pos);}T.getseq();memset(f,0x7f,sizeof f);f[0]=-inf;for(int i=1;i<=n;++i){int t=upper_bound(f,f+n+1,a[i])-f;f[t]=a[i];ans[a[i]]=t;}for(int i=1;i<=n;++i)printf("%d\n",ans[i]=max(ans[i-1],ans[i]));puts("");return 0; }

轉載于:https://www.cnblogs.com/jklover/p/10163705.html

總結

以上是生活随笔為你收集整理的bzoj 3173 最长上升子序列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。