FJOI2015 火星商店問題 分治 可持久化

2022-07-13 20:27:12 字數 1856 閱讀 3729

題目描述

火星上的一條商業街裡按照商店的編號1,2 ,…,n ,依次排列著n個商店。商店裡**的琳琅滿目的商品中,每種商品都用乙個非負整數val來標價。每個商店每天都有可能進一些新商品,其標價可能與已有商品相同。

對於給定的按時間順序排列的事件,計算每個購物的火星人的在本次購物活動中最喜歡的商品,即輸出val xor x的最大值。這裡所說的按時間順序排列的事件是指以下2種事件:

事件0,用三個整數0,s,v,表示編號為s的商店在當日新進一種標價為v 的商品。

事件1,用5個整數1,l,r,x,d,表示一位火星人當日在編號為l到r的商店購買d天內的商品,該火星人的喜好密碼為x。

題解

考慮如果沒有時間限制,我們可以選取的區間為連續一段,那樣就是簡單的按位貪心,可以用可持久化trie維護。

我們可以每次都重構trie,複雜度是對的。

**

#include#include

#include

#include

#define n 210002

using

namespace

std;

vector

vec[n<<2

];int len=18,tot,inv[20

],t[n],ans[n],n,m,tim,top;

inline

intrd()

while(isdigit(c))

return f?-x:x;

}struct

trie

inline

int query(int now,int pre,int x,int

deep)

}tr;

struct

node

}co[n],q1[n],q2[n];

struct nodq[n];

void calc(int cnt,int l,int

r)

for(int i=0;ii)

}void upd(int cnt,int l,int r,int l,int r,int

x)

int mid=(l+r)>>1

;

if(mid>=l)upd(cnt<<1

,l,mid,l,r,x);

if(mid1|1,mid+1

,r,l,r,x);

}void solve(int cnt,int l,int r,int l,int

r)

for(int i=1;i<=o;++i)co[l+i-1]=q1[i];

for(int i=1;i<=p;++i)co[l+o+i-1]=q2[i];

if(l!=r)solve(cnt<<1,l,mid,l,l+o-1

); solve(cnt

<<1|1,mid+1,r,l+o,r);

}int

main();

ans[top]=tr.query(t[r],t[l-1

],x,len);

} else

; }

}sort(co+1,co+tim+1

);

for(int i=1;i<=top;++i)upd(1,1

,tim,q[i].st,q[i].en,i);

solve(

1,1,tim,1

,tim);

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

%d\n

",ans[i]);

return0;

}

FJOI2015 火星商店問題

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

題解 FJOI2015火星商店問題

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

洛谷 FJOI2015 火星商店問題

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