P4585 火星商店問題

2022-02-27 07:43:38 字數 1695 閱讀 3370

線段樹分治+可持久化 trie

如果只有特殊商品,那麼直接乙個可持久化 trie,根據異或的性質,在 trie 上貪心走路徑就行了

所以這部分特殊商品單獨維護,考慮其他普通商品如何維護

考慮以商店編號為下標,建立線段樹。那麼每個商店區間 \([l,r]\) 可以被分為 \(o(\log n)\) 個區間,我們分別對這些區間打上標記來維護商品資訊

其實就是線段樹再套乙個可持久化 trie,每個節點維護兩個vector,分別表示每個 trie 的根,以及對應的新增時的時間。然後每次新增的時候,加乙個根,再拿上乙個根一起可持久化建樹就行了

詢問的時候,還是把詢問的商店區間分成若干小區間,對於每個完全覆蓋了個區間,二分一下此節點最靠前的乙個符合條件的時間,然後拿那個時間對應的根,和當前新增的最後乙個根,在可持久化 trie 上貪心取最大值

複雜度 \(o(n\log n\log t)\)

#include#include#include#include#include#include#include#define reg register

#define en puts("")

inline int read()

while(c>='0'&&c<='9')

return y?x:-x;

}int n,m;

#define max 18

#define n 100006

struct triedizhi[n*128],*root[n],*null=&dizhi[0];

int tot;

inline void new(node *&a)

void insert(node *tree,node *last,int x,int pos)

int ask(node *left,node *right,int x,int pos)

}trie;

struct segdizhi[n*2],*root=&dizhi[0];

int tot;

void build(node *tree,int l,int r)

void change(node *tree,int l,int r,int pos,int val,int day)

int ask(node *tree,int l,int r,int ql,int qr,int x,int lim,int day)

// printf("seg::ask : ans=%d\n",ans);

return trie.ask(tree->root[ans-1],tree->now_root,x,max);

} int mid=(l+r)>>1,ret=0;

if(ql<=mid) ret=std::max(ret,ask(tree->ls,l,mid,ql,qr,x,lim,day));

if(qr>mid) ret=std::max(ret,ask(tree->rs,mid+1,r,ql,qr,x,lim,day));

return ret;

}}seg;

int main()

seg.build(seg.root,1,n);

reg int op,x,y,day=0;int l,r;

while(m--)

else

} return 0;

}

FJOI2015 火星商店問題

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

題解 FJOI2015火星商店問題

好幾天之前做的題目了,一直想寫一下部落格也沒騰出時間來,今天趕緊把坑給填上呼呼呼 這道題首先如果只考慮每個商店中沒有時間限制的物品時,我們只需要使用一棵可持久化trie樹來維護區間內的異或最大值即可,這樣我們可以把兩部分的問題分離開來。之後我們再考慮有時間限制與編號限制的情況下,該怎樣做?無腦做法線...

洛谷 FJOI2015 火星商店問題

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