time limit: 10 sec memory limit: 128 mb
submit: 2294 solved: 1153
[submit][status][discuss]
給定乙個序列,初始為空。現在我們將1到n的數字插入到序列中,每次將乙個數字插入到乙個特定的位置。每插入乙個數字,我們都想知道此時最長上公升子串行長度是多少?
第一行乙個整數n,表示我們要將1到n插入序列中,接下是n個數字,第k個數字xk,表示我們將k插入到位置xk(0<=xk<=k-1,1<=k<=n)
n行,第i行表示i插入xi位置後序列的最長上公升子串行的長度是多少。
30 0 211
2100%的資料 n<=100000
首先先不管答案,先看看怎麼維護序列。
然後發現這就是乙個裸的splay/treap,找到第k大然後旋到根然後把當前點查到後繼的左兒子就ojbk了。
所以怎麼回答詢問呢???
我們設ans[i]為在最終序列裡的以i結尾的最長上公升子串行長度,那麼第i次詢問的答案就是max(ans[1],ans[2],,,,ans[i])。
為什麼呢?
因為後加入的肯定都比前i個數大,所以不會對答案產生影響,所以最終序列以前i個數結尾的lis就是第i次詢問的答案。
#include#define ll long long#define maxn 100005
using
namespace
std;
int root,ch[maxn][2
];int
f[maxn],siz[maxn],pos;
intn,m,ans[maxn],g[maxn];
intb[maxn],cnt,tot;
inline
intget(int
x)inline
void update(int
x)inline
void rotate(int
x)inline
void splay(int
x)inline
void kth(int
k) now=ch[now][1
]; }
}}inline
void
insert_front()
int now=root,fa;
while
(now)
siz[++cnt]=1,f[cnt]=fa,ch[fa][0]=cnt;
update(fa);
}inline
void
insert_back()
siz[root]++;
int now=ch[root][1
];
while(ch[now][0]) siz[now]++,now=ch[now][0
]; siz[now]++;
ch[now][
0]=++cnt,siz[cnt]=1,f[cnt]=now;
}inline
void updata(int x,int
y)inline
int query(int
x)inline
void build(int
x)int
main()
}build(root);
for(int i=1;i<=n;i++)
for(int i=1;i<=n;i++)
return0;
}
Tjoi2013 最長上公升子串行 樹狀陣列 二分
description 給定乙個序列,初始為空。現在我們將1到n的數字插入到序列中,每次將乙個數字插入到乙個特定的位置。每插入乙個數字,我們都想知道此時最長上公升子串行長度是多少?sample input 3 0 0 2 sample output 1 1 2這道題首先我們的思路是求出每個數放的位置...
P4309 TJOI2013 最長上公升子串行
給定乙個序列,初始為空。現在我們將1到n的數字插入到序列中,每次將乙個數字插入到乙個特定的位置。每插入乙個數字,我們都想知道此時最長上公升子串行長度是多少?因為每次插入的數是按順序從小到大的,所以我們可以從後往前計算 我們先用 vector 自帶的 insert 函式得到所有數都插入完後的序列,然後...
TJOI2018 最長上公升子串行
觀察題目 在第 i 輪操作時,將數字 i 插入 插入的數字是當前最大的 如果答案與上次不同,新的lis必以 i 結尾 以 i 結尾的lis無法再伸長 因為比 i 小的都插入完了 也就是說,加入 i 1 到 n 的數,不會對以 i 結尾的上公升子串行有影響,所以我們不用去動態地維護lis的大小,只需要...