題目描述
火星上的一條商業街裡按照商店的編號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異或的最大值。我們...