買禮物 鍊錶 線段樹)

2021-10-19 09:29:30 字數 1285 閱讀 1658

在賣禮物的超市中有n個櫃子,每個櫃子裡都擺放了乙個禮物,每個禮物有自己的乙個編號,第i個櫃子裡的禮物編號為ai​。

茶山牛想給牛牛和牛妹買相同編號的禮物,但禮物有可能在某個時刻被其他人買走,而且櫃子數量太多,因此茶山牛在某個時刻只想知道某乙個櫃子區間是否能買到兩件相同編號的禮物。

具體來說,有q次操作,格式如下:

1x,第x個櫃子裡的禮物被買走,保證此時這個櫃子裡的禮物還在。

2 l r,茶山牛詢問第l到第r個櫃子未被買走的禮物中是否有兩個禮物編號相同。

對每次茶山牛的詢問輸出一行乙個整數,如果在指定的區間內有兩個禮物編號相同則輸出1,否則輸出0。
思路:預處理每個數的最近前後位置,類似鍊錶,然後線段樹存每個下標的next位置,查詢看[l,r]的最小值(對應最近的nxet)是否<=r。線段樹上修改即修改last[i]的next[i]的位置。

#include#include#include#include#include#include#include#include#include#define debug(a) cout<<#a<<"="struct treetree[maxn*4];

void push_up(ll p)

void build(ll p,ll l,ll r)

ll mid=(l+r)>>1;

build(p*2,l,mid);

build(p*2+1,mid+1,r);

push_up(p);

}void modify(ll p,ll l,ll r,ll d)

ll mid=(tree[p].l+tree[p].r)>>1;

if(l<=mid) modify(p*2,l,r,d);

if(r>mid) modify(p*2+1,l,r,d);

push_up(p);

}ll query(ll p,ll l,ll r)

ll ans=inf;

ll mid=(tree[p].l+tree[p].r)>>1;

if(l<=mid) ans=min(ans,query(p*2,l,r));

if(r>mid) ans=min(ans,query(p*2+1,l,r));

return ans;

}int main(void)

for(ll i=1;i<=1e6;i++) v[i].push_back(inf);

for(ll i=1;i<=1e6;i++)

else cout<<"0"<<"\n";

}}return 0;

}

E 買禮物(鍊錶 線段樹)

傳送門 題目大意 給出乙個序列,有以下兩種操作 解題思路 很好的一道題,之前在洛谷寫過查詢區間內是否有兩數相同是用莫隊維護的區間種類數,但是本題如果寫莫隊估計要tle tletl e,然後學到了這手很強的問題轉化技巧 對於區間內的每個數,我們只需要知道它右邊離他最近相同數的在哪個位置,然後判斷區間內...

買禮物 題解 線段樹 思維

本質上還是乙個線段樹裸題 就是要思考這個線段樹記錄的是什麼 線段樹記錄區間中每個元素的下乙個元素的最小值 這樣只要查詢的時候小於右邊界即可 而如果把某個值變為空,即模擬一下鍊錶操作即可 那麼就變成了單點修改,區間查詢 include define fi first define se second ...

線段樹 買水果

水果姐今天心情不錯,來到了水果街。水果街有n家水果店,呈直線結構,編號為1 n,每家店能買水果也能賣水果,並且同一家店賣與買的 一樣。學過oi的水果姐迅速發現了乙個賺錢的方法 在某家水果店買乙個水果,再到另外一家店賣出去,賺差價。就在水果姐竊喜的時候,cgh突然出現,他為了為難水果姐,給出m個問題,...