uoj218 火車管理 主席樹

2022-05-07 22:30:11 字數 1522 閱讀 1054

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

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

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

假設當前的時間為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<<"="<>1)

typedef long long ll;

using namespace std;

void file()

templatevoid 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;

int main()

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