好幾天之前做的題目了,一直想寫一下部落格也沒騰出時間來,今天趕緊把坑給填上呼呼呼~
這道題首先如果只考慮每個商店中沒有時間限制的物品時,我們只需要使用一棵可持久化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 usingnamespace
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...