uoj218 火車管理 主席樹

2021-09-12 10:32:21 字數 1987 閱讀 9517

維護乙個棧,每次區間壓棧,單點彈棧,區間詢問棧頂的元素和。

如果沒有彈棧的操作的話,我們每一次只需要在一顆線段樹上面區間賦值即可。

加上彈棧操作,我們每次就需要知道當前棧頂元素的上乙個元素是什麼,考慮用主席樹來維護每乙個時刻每乙個位置的最近一次的修改位置。

假設當前的時間為x且我們需要彈棧,那麼我們需要先查詢得到最近的一次時間y,然後查詢y-1的修改時間z,那麼我們就得到了棧頂下面的元素的修改時間。

然後我們需要將x點的這個元素的時間改為z,然後更新查詢線段樹上的答案即可。

不難發現我們實際上是向前維護了乙個最近修改時間的鍊錶,由於主席樹的繼承性質,直接查詢y-1使得我們的答案是正確的。

/************************************====

* author : ylsoi

* time : 2019.3.10

* problem : uoj218

* e-mail : [email protected]

* ***********************************=*/

#include

#define rep(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)

#define drep(i,a,b) for(int i=a,i##_end_=b;i>=i##_end_;--i)

#define debug(x) cout<<#x<<"="<#define fi first

#define se second

#define mk make_pair

#define pb push_back

#define mid ((l+r)>>1)

typedef

long

long ll;

using

namespace std;

void

file()

template

<

typename t>

void

read

(t &_)

string proc()

const

int maxn=

5e5+10;

int n,m,ty,ans,root[maxn]

,tot,w[maxn]

;struct segment_tree

}void

update

(int o,

int l,

int r,

int l,

int r,

int x,

int y)

}int

query_sum

(int o,

int l,

int r,

int l,

int r)

}int

query_las

(int o,

int l,

int r,

int p)

#undef lc

#undef rc

}t1;

struct chairman_treet[maxn*

120]

;void

insert

(int

&o,int l,

int r,

int l,

int r,

int x)

}int

query

(int o,

int l,

int r,

int p)

}t2;

intmain()

else

if(op==2)

}else

/*rep(j,1,n)printf("%d ",t1.query_sum(1,1,n,j,j));

printf("\n");*/

}//cerr}

uoj218 火車管理 主席樹

維護乙個棧,每次區間壓棧,單點彈棧,區間詢問棧頂的元素和。如果沒有彈棧的操作的話,我們每一次只需要在一顆線段樹上面區間賦值即可。加上彈棧操作,我們每次就需要知道當前棧頂元素的上乙個元素是什麼,考慮用主席樹來維護每乙個時刻每乙個位置的最近一次的修改位置。假設當前的時間為x且我們需要彈棧,那麼我們需要先...

UOJ 218 UNR 1 火車管理

維護一顆主席樹 火車入棧相當於區間修改,彈棧相當於返回歷史版本 維護線段樹區間求和 ps 之前沒把 放上來 extra的最後乙個點re,orz蒟蒻無能為力 include include include include include const int maxn 600005 const int ...

UOJ 218 UNR 1 火車管理

注意記憶體有些卡,有一些技巧 1.首先對於查詢的線段樹是全域性的,不需要動態開點 2.對於線段樹中的乙個節點 x 如果它的左右兒子都沒有兒子,那麼下一次做區間覆蓋時,就不需要對 x 新建兩個節點 include define lo o 1 define ro o 1 1 using namespac...