UOJ 218 UNR 1 火車管理

2022-02-27 17:46:07 字數 1542 閱讀 3082

維護一顆主席樹

火車入棧相當於區間修改,彈棧相當於返回歷史版本

維護線段樹區間求和

ps:之前沒把**放上來 

extra的最後乙個點re,orz蒟蒻無能為力

#include#include

#include

#include

#include

const

int maxn = 600005

;const

int maxm = 40000007

;int

tt[maxm],ls[maxm],tag[maxm],rs[maxm];

int tg[maxn<<2],sum[maxn<<2],sz,rt[maxn<<1],a[maxn<<1

];int

n,m,ty;

intread()

while ('0'

<=c&&c<='9')

return t*f;

}void merge(int

k) void modify(int &k,int l,int r,int rt,int tl,int tr,int

v) merge(rt);

int mid=(l+r)>>1

; ls[k]=ls[rt];rs[k]=rs[rt];

if(mid>=tl)modify(ls[k],l,mid,ls[rt],tl,tr,v);

if(mid1

,r,rs[rt],tl,tr,v);

}int query(int l,int r,int rt,int

pos)

void pushdown(int l,int r,int

rt)void modify2(int l,int r,int rt,int tl,int tr,int

v)

int mid=(l+r)>>1

;

if(mid>=tl)modify2(l,mid,rt<<1

,tl,tr,v);

if(mid1,r,rt<<1|1

,tl,tr,v);

sum[rt]=sum[rt<<1]+sum[rt<<1|1

]; }

int getsum(int l,int r,int rt,int tl,int

tr)

int mid=(l+r)>>1

;

int ret=0

;

if(mid>=tl)ret+=getsum(l,mid,rt<<1

,tl,tr);

if(tr>mid)ret+=getsum(mid+1,r,rt<<1|1

,tl,tr);

return

ret;

}int

main()

else

if (opt==2

)

continue

; }

else

}return0;

}

UOJ 218 UNR 1 火車管理

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

uoj 218 UNR 1 火車管理

想了一下就想出了log 2的,之後剛了乙個下午嘗試去掉乙個log結果發現把set改成優先佇列就過了 log 2的自然做法 彈棧就單點查詢,把經過的所有區間內時間最大的彈掉,第二大的就是新的值 彈掉之後下傳,注意只需要下傳乙個標記,往下一共有log個區間 時間是log 2的,用優先佇列即可通過並且不是...

uoj218 火車管理 主席樹

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