DP 二分 JZOJ 3467 最長上公升子串行

2022-04-30 20:18:15 字數 1590 閱讀 9393

description

維護乙個序列,使它可以進行下面兩種操作:

1.在末尾新增乙個數字x

2.將整個序列變成第x次操作後的樣子

在每次操作後,輸出當前序列的最長上公升子串行的長度

序列初始時為空

input

輸入檔案lis.in的第一行有乙個正整數n,表示操作個數。接下來n行每行有兩個整數op,x。如果op為0,則表示新增x這個數字;如果op為1,則表示回到第x次操作之後。

output

對於每次操作,在輸出檔案lis.out中輸出乙個答案,表示當前最長上公升子串行的長度

sample input

5

0 20 0

1 01 0

0 5

sample output

110

01【樣例說明】

第一次操作後,序列為 2

第二次操作後,序列為2 0

第三次操作後,序列為(空)

第四次操作後,序列為(空)

第五次操作後,序列為 5

data constraint

30%的資料  n<=1000

另外20%的資料沒有第二個操作

80%的資料 n<=200000

100%的資料 n<=500000且所有輸入的數字都是長整型範圍內的非負整數

分析我們可以容易發現這個題的資料輸入呈乙個樹形,但是我們無法每次都對一條鏈求最長上公升子串行。

然後想到dfs可以重置一些東西,記錄一些相關的變化量再退回即可。

(然後傳統dfs居然爆棧了?)手寫乙個while版的dfs= =

#include #include 

#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()

view code

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...