P4585 [FJOI2015] 火星商店问题
题意
有 \(n\) 个商店,编号 \(1\) 到 \(n\),很多种商品,每个商品有个价值。
现在有集中操作:
0 s v 新开一天,并在这一天给编号为 \(s\) 的商店进货 \(v\)。
1 l r x d 一个人来编号属于 \([l,r]\) 的商店买东西,设当前为第 \(now\) 天,那么祂可以买到 \([now-d+1,now]\) 天进的货,问祂能买到的物品中,价值异或 \(x\) 的最大值。
每个商店都有一个物品被神秘力量所眷顾,这个物品可以在任何时候买到,不受天数的限制,这些物品将会在开头给出祂们的价值。
所有输入的数在 \([0,10^5]\) 范围内。
思路
外层用一个线段树维护商店编号,里面用 \(Trie\) 维护。为了解决时间这个维度,\(Trie\) 上的每个节点记录到祂的最大时间,在 \(Trie\) 上游走时判断一下最晚的时间是否在合法区间内。可以把被神秘力量所眷顾的物品插入的时间设为无穷大,判断合法时不要管时间小于等于 \(now\),这是没有影响的。
时间复杂度 \(\mathcal O(n\log^2n)\)
代码
拿下最劣解。
/*
Luogu P4585 [FJOI2015] 火星商店问题
2026-04-22
*/
#include<bits/stdc++.h>
using namespace std;
namespace IO{
template<typename T>
inline void read(T&x){
x=0;char c=getchar();bool f=0;
while(!isdigit(c)) c=='-'?f=1:0,c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
f?x=-x:0;
}
template<typename T>
inline void write(T x){
if(x==0){putchar('0');return ;}
x<0?x=-x,putchar('-'):0;short st[50],top=0;
while(x) st[++top]=x%10,x/=10;
while(top) putchar(st[top--]+'0');
}
inline void read(char&c){c=getchar();while(isspace(c)) c=getchar();}
inline void write(char c){putchar(c);}
inline void read(string&s){s.clear();char c;read(c);while(!isspace(c)&&~c) s+=c,c=getchar();}
inline void write(string s){for(int i=0,len=s.size();i<len;i++) putchar(s[i]);}
template<typename T>inline void write(T*x){while(*x) putchar(*(x++));}
template<typename T,typename...T2> inline void read(T&x,T2&...y){read(x),read(y...);}
template<typename T,typename...T2> inline void write(const T x,const T2...y){write(x),putchar(' '),write(y...),sizeof...(y)==1?putchar('\n'):0;}
}using namespace IO;
const int maxn=100010;
int n,m,now;
class Trie{
private:
struct node{int ch[2],ti;}t[maxn*17*17];
int rt[maxn*17],cnt;
public:
void insert(int id,int x,int ti){
if(rt[id]==0) rt[id]=++cnt;
int u=rt[id];t[u].ti=max(t[u].ti,ti);
for(int i=17;i>=0;i--){
int ch=!!(x&(1<<i));
if(t[u].ch[ch]==0) t[u].ch[ch]=++cnt;
u=t[u].ch[ch];
t[u].ti=max(t[u].ti,ti);
}
}
int query(int id,int x,int lt){
int u=rt[id],ans=0;
for(int i=17;i>=0;i--){
int ch=!(x&(1<<i));
if(t[t[u].ch[ch]].ti>=lt) u=t[u].ch[ch],ans|=(1<<i);
else u=t[u].ch[!ch];
}
return ans;
}
}Tr;
class Segment_Tree{
private:
void insert(int u,int l,int r,int d,int z,int ti){
if(l>d||r<d) return ;
Tr.insert(u,z,ti);
if(l==r) return ;
int mid=l+r>>1;
insert(u<<1,l,mid,d,z,ti),insert(u<<1|1,mid+1,r,d,z,ti);
}
int query(int u,int l,int r,int ll,int rr,int x,int lt){
if(l>rr||r<ll) return 0;
int ans=Tr.query(u,x,lt);
if(ll<=l&&r<=rr) return ans;
int mid=l+r>>1;
return max({query(u<<1,l,mid,ll,rr,x,lt),query(u<<1|1,mid+1,r,ll,rr,x,lt)});
}
public:
void insert(int d,int z,int ti){insert(1,1,n,d,z,ti);}
int query(int l,int r,int z,int lt){return query(1,1,n,l,r,z,lt);}
}sgt;
signed main(){
read(n,m);
for(int i=1;i<=n;i++){
int x;read(x);
sgt.insert(i,x,20120515);
}
int now=0;
for(int i=1;i<=m;i++){
int op,s,v,l,r,x,d;read(op);
if(op){
read(l,r,x,d);
write(sgt.query(l,r,x,now-d+1));write("\n");
}
else{
read(s,v);
now++;
sgt.insert(s,v,now);
}
}
return 0;
}

浙公网安备 33010602011771号