description
維護乙個序列,使它可以進行下面兩種操作:
1.在末尾新增乙個數字x
2.將整個序列變成第x次操作後的樣子
在每次操作後,輸出當前序列的最長上公升子串行的長度
序列初始時為空
input
輸入檔案lis.in的第一行有乙個正整數n,表示操作個數。接下來n行每行有兩個整數op,x。如果op為0,則表示新增x這個數字;如果op為1,則表示回到第x次操作之後。
output
對於每次操作,在輸出檔案lis.out中輸出乙個答案,表示當前最長上公升子串行的長度
sample input
5sample output0 20 0
1 01 0
0 5
110data constraint01【樣例說明】
第一次操作後,序列為 2
第二次操作後,序列為2 0
第三次操作後,序列為(空)
第四次操作後,序列為(空)
第五次操作後,序列為 5
30%的資料 n<=1000
另外20%的資料沒有第二個操作
80%的資料 n<=200000
100%的資料 n<=500000且所有輸入的數字都是長整型範圍內的非負整數
分析我們可以容易發現這個題的資料輸入呈乙個樹形,但是我們無法每次都對一條鏈求最長上公升子串行。
然後想到dfs可以重置一些東西,記錄一些相關的變化量再退回即可。
(然後傳統dfs居然爆棧了?)手寫乙個while版的dfs= =
#include #includeview code#include
using
namespace
std;
const
int n=500001
;struct
edge g[n];
struct
d stk[n];
inttop;
intcnt,list[n];
intf[n],d[n],num[n],w[n];
intpcnt,mlen;
intn;
void add(int u,int
v) void dfs(int
u) ;
if (!list[stk[top].u]) break
;
int i=list[stk[top].u];
list[stk[top].u]=g[i].nx;
stk[top].v=g[i].v;
stk[top].b=0
;
if (d[mlen]
else
f[stk[top].v]=mlen;
top++;
stk[top].u=stk[top-1
].v;
}}void
init() }d[
0]=-2147483647;mlen=0;}
void
print()
intmain()
1081 最長上公升子串行 (dp 二分)
pipi又來考大家最長上公升子串行問題了 不過這次它想為難一下你 給你乙個整數序列,包含n個整數,要你求最長上公升子串行的長度 多組輸入 第一行為乙個整數n,1 n 1000000 第二行包括n個整數,每個整數均在int範圍內 輸出乙個整數,表示最長上公升子串行的長度。51 2 5 4 7 incl...
LIS 最長上公升序列(DP 二分優化)
求乙個數列的最長上公升序列 動態規劃法 o n 2 1 dp 2int lis int a,intn 3 16 17 18return cnt 1 因為初始化為0,所以返回結果 1 19 貪心 二分法 o nlogn 分析 要讓乙個序列具有最長上公升子串行,其實就是保證子串行中的每個元素盡可能小,降...
LIS 最長上公升子串行 dp 二分優化
建立乙個陣列res maxn res i 用來記錄以i位置為結尾的最長的子串行,那麼我們要求res這個陣列裡的最大值 注意不是res n 所以當我們在求res i 時,需要從0到i 1掃一遍,看看通過哪個點 鬆弛 因為這個演算法好像迪科斯徹最短路,所以借用這個名詞來解釋一下 這樣 如下 includ...