題解 FJOI2015火星商店問題

2022-02-27 09:43:51 字數 2131 閱讀 6350

好幾天之前做的題目了,一直想寫一下部落格也沒騰出時間來,今天趕緊把坑給填上呼呼呼~

這道題首先如果只考慮每個商店中沒有時間限制的物品時,我們只需要使用一棵可持久化trie樹來維護區間內的異或最大值即可,這樣我們可以把兩部分的問題分離開來。

之後我們再考慮有時間限制與編號限制的情況下,該怎樣做?無腦做法線段樹套trie,直接在對應的區間trie樹上貪心,如果該條邊的最後更新時間在允許的範圍內,說明可以走這條邊。雖然這樣也可以卡過去(主要在於卡空間),但我們來介紹一種更加妙妙的線段樹分治做法。其實我感覺在這題的體現上就是離線版樹套樹?機房大佬貌似不認可,但我確實是這樣覺得噠。

1.如果當前處理的區間(l,r)完全包含於詢問區間,我們將這個詢問的區間在這一層進行處理。(這樣的詢問均不再下傳,跳過後續步驟)

2.如果詢問的區間有涉及(l,mid)的範圍,遞迴左區間處理。

3.如果詢問的區間有涉及(mid+1,r)的範圍,遞迴右區間處理。

(本題分治的區間表示時間的範圍,可持久化trie負責處理編號的限制)。

這樣的複雜度是多少?我們可以分處理trie樹與查詢的兩個方面來分析。處理trie樹時,我們插入乙個值是log的複雜度,而包含乙個修改的總分治區間數也是log個,所以是\(o(nlog^n)\)的複雜度。查詢也是log的複雜度,乙個查詢最多被分別查詢 log 次。所以複雜度依然是 \(o(nlog^n)\) 的。

#include using

namespace

std;

#define maxn 1000000

intn, m, sz, qt, nt, tot, cnt, timer;

int ans[maxn], sum[maxn * 5

], id[maxn], q[maxn];

int bit[30], ch[maxn * 5][2

], num[maxn], root[maxn];

intread()

while(c >= '

0' && c <= '

9') x = x * 10 + c - '

0', c =getchar();

return x *k;

}struct

ques

q[maxn];

struct

modify

}p[maxn], ql[maxn], qr[maxn];

void ins(int now, int last, int x, int

val)

int query(int l, int r, int x, int

val)

int check(int

v)

return

ret;

}void work(int l, int

r)

for(int i = 1; i <= qt; i ++)

}void divide(int l, int r, int l, int r, int

pres)

for(int i = 1; i <= ll; i ++) p[i + l - 1] =ql[i];

for(int i = 1; i <= rr; i ++) p[i + l + ll - 1] =qr[i];

int ind = 0

;

for(int i = 1; i <= pres; i ++)

divide(l, l + ll - 1

, l, mid, ind);

ind = 0

;

for(int i = 1; i <= pres; i ++)

divide(l + ll, r, mid + 1

, r, ind);

}int

main()

else

}sort(p + 1, p + 1 +tot);

for(int i = 1; i <= cnt; i ++) id[i] =i;

divide(

1, tot, 1

, timer, cnt);

for(int i = 1; i <= cnt; i ++) printf("

%d\n

", ans[i]);

return0;

}

FJOI2015 火星商店問題

線段樹分治。以時間軸建立線段樹,每乙個線段樹節點,存放 l,r 時間內,有影響的操作1,建立可持久化trie樹,trie樹以商店位置為root,就可以支援商店的區間查詢,然後將操作0,按照商店位置排序,進行線段樹分治,每次到乙個節點,先把操作0插入trie樹,然後把所有當前時間記憶體的有影響的操作1...

洛谷 FJOI2015 火星商店問題

初見安 這裡是傳送門 洛谷p4585 fjoi2015 火星商店問題 聽說是分治線段樹套可持久化trie 蒟蒻不會分治線段樹,就寫了乙個線段樹套trie。題意就是 n個初始為空的集合,m個操作。操作有 向某集合中加入乙個整數或查詢最近d次向編號在 l,r 中的集合加入的元素中,與x異或的最大值。我們...

FJOI2015 火星商店問題 線段樹分治

這道題的每個詢問都有兩個區間,乙個是時間區間,乙個是商店編號區間。每個購買也是和時間商店編號有關。如何讓這兩個引數聯絡起來,就需要用到線段樹表示時間區間。線段樹可以把時間區間分細。對於每乙個詢問,它都有乙個時間區間 cn t1 d 1,c nt1 cnt 1 d 1,cnt 1 cnt1 d 1 c...