Description

火星上的一条商业街里按照商店的编号1,2 ,…,n ,依次排列着n个商店。商店里出售的琳琅满目的商品中,每种商品都用一个非负整数val来标价。每个商店每天都有可能进一些新商品,其标价可能与已有商品相同。 
火星人在这条商业街购物时,通常会逛这条商业街某一段路上的所有商店,譬如说商店编号在区间[L,R]中的商店,从中挑选1件自己最喜欢的商品。每个火星人对商品的喜好标准各不相同。通常每个火星人都有一个自己的喜好密码x。对每种标价为val的商品,喜好密码为x的火星人对这种商品的喜好程度与val异或x的值成正比。也就是说,val xor x的值越大,他就越喜欢该商品。每个火星人的购物卡在所有商店中只能购买最近d天内(含当天)进货的商品。另外,每个商店都有一种特殊商品不受进货日期限制,每位火星人在任何时刻都可以选择该特殊商品。每个商店中每种商品都能保证供应,不存在商品缺货的问题。 
对于给定的按时间顺序排列的事件,计算每个购物的火星人的在本次购物活动中最喜欢的商品,即输出val xor x的最大值。这里所说的按时间顺序排列的事件是指以下2种事件: 
事件0,用三个整数0,s,v,表示编号为s的商店在当日新进一种标价为v 的商品。 
事件1,用5个整数1,L,R,x,d,表示一位火星人当日在编号为L到R的商店购买d天内的商品,该火星人的喜好密码为x。

Input

第1行中给出2个正整数n,m,分别表示商店总数和事件总数。 
第2行中有n个整数,第i个整数表示商店i的特殊商品标价。 
接下来的m行,每行表示1个事件。每天的事件按照先事件0,后事件1的顺序排列。 

Output

将计算出的每个事件1的val xor x的最大值依次输出。

Sample Input

4 6
1 2 3 4
1 1 4 1 0
0 1 4
0 1 3
1 1 1 1 0
1 1 1 1 1
1 1 2 1 2

Sample Output

5
0
2
5

HINT

n, m <= 100000
数据中,价格不大于100000

Source

显然呢这道题可以用线段树套可持久化$Trie$来实现,不过不是我们讨论的范围
我们考虑每个修改对询问的影响是一段区间
按时间建立线段树,那么每个询问对应了线段树不超过$logn$个节点,每次修改对应着从该时间点到根节点的路径
所以每个修改对$logn$个节点有贡献,因此我们在回答每个节点的询问前,直接暴力把对该节点有影响的修改插进线段树即可
因为询问被拆成了许多线段树节点,于是要对这些被拆的询问取$max$
代码:
 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#define M 100010
#define ls node<<1
#define rs node<<1|1
using namespace std; int n,m,cnt,cnt1,cnt2;
int rt[M],f[M],ans[M];
vector<int>seg[M<<];
struct CG{int s,v,t;}q[M],tmp1[M],tmp2[M];
struct ASK{int l,r,l1,r1,x;}p[M];
bool cmp(CG a1,CG a2) {return a1.s<a2.s;} struct Trie
{
int cnt;
int val[M<<],ch[M<<][];
void insert(int &now,int pre,int w,int o)
{ now=++cnt,val[now]=val[pre]+;
ch[now][]=ch[pre][];ch[now][]=ch[pre][];
if(o==-) return;bool c=w&(<<o);
insert(ch[now][c],ch[pre][c],w,o-);
}
int query(int now,int pre,int w,int o)
{
if(o==-) return ;
bool c=w&(<<o);
int tmp=val[ch[now][c^]]-val[ch[pre][c^]];
if(tmp) return query(ch[now][c^],ch[pre][c^],w,o-)+(<<o);
else return query(ch[now][c],ch[pre][c],w,o-);
}
}T; void insert(int node,int l,int r,int l1,int r1,int id)
{
if(l1>r1) return;
if(l1<=l&&r1>=r) {seg[node].push_back(id);return;}
int mid=(l+r)/;
if(l1<=mid) insert(ls,l,mid,l1,r1,id);
if(r1>mid) insert(rs,mid+,r,l1,r1,id);
} int get(int v)
{
int l=,r=cnt,ans=;
while(l<=r)
{
int mid=(l+r)/;
if(f[mid]<=v) ans=mid,l=mid+;
else r=mid-;
}
return ans;
} void cal(int node,int l,int r)
{
cnt=T.cnt=;
for(int i=l;i<=r;i++)
{
f[++cnt]=q[i].s;
T.insert(rt[cnt],rt[cnt-],q[i].v,);
}
for(int i=;i<seg[node].size();i++)
{
int id=seg[node][i];
int l=get(p[id].l-);
int r=get(p[id].r);
ans[id]=max(ans[id],T.query(rt[r],rt[l],p[id].x,));
}
} void solve(int node,int l,int r,int l1,int r1)
{
if(l1>r1) return;
cal(node,l,r);
if(l==r) return;
int mid=(l+r)/,t1=,t2=;
for(int i=l1;i<=r1;i++)
{
if(q[i].t<=mid) tmp1[++t1]=q[i];
else tmp2[++t2]=q[i];
}
for(int i=;i<=t1;i++) q[i+l1-]=tmp1[i];
for(int i=;i<=t2;i++) q[i+l1-+t1]=tmp2[i];
solve(ls,l,mid,l1,l1+t1-);
solve(rs,mid+,r,l1+t1,r1);
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
int x;scanf("%d",&x);
T.insert(rt[i],rt[i-],x,);
}
for(int i=;i<=m;i++)
{
int opt;scanf("%d",&opt);
if(!opt)
{
int s,v;scanf("%d%d",&s,&v);
cnt1++;q[cnt1]=(CG){s,v,cnt1};
}
else
{
int l,r,x,d;scanf("%d%d%d%d",&l,&r,&x,&d);
ans[++cnt2]=T.query(rt[r],rt[l-],x,);
p[cnt2]=(ASK){l,r,max(,cnt1-d+),cnt1,x};
}
}
for(int i=;i<=cnt2;i++)
insert(,,cnt1,p[i].l1,p[i].r1,i);
sort(q+,q++cnt1,cmp);
solve(,,cnt1,,cnt1);
for(int i=;i<=cnt2;i++) printf("%d\n",ans[i]);
return ;
}

[BZOJ4137]火星商店问题的更多相关文章

  1. 【BZOJ4137】火星商店问题(线段树分治,可持久化Trie)

    [BZOJ4137]火星商店问题(线段树分治,可持久化Trie) 题面 洛谷 BZOJ权限题 题解 显然可以树套树,外层线段树,内层可持久化Trie来做. 所以我们需要更加优美的做法.--线段树分治. ...

  2. [FJOI2015]火星商店问题

    [FJOI2015]火星商店问题 神仙线段树分治...不过我不会. 这题用线段树套可持久化Trie还是能写的. 常数有点大,洛谷垫底水平. // luogu-judger-enable-o2 #inc ...

  3. 【LG4585】[FJOI2015]火星商店问题

    [LG4585][FJOI2015]火星商店问题 题面 bzoj权限题 洛谷 \(Notice:\) 关于题面的几个比较坑的地方: "一天"不是一个操作,而是有0操作就相当于一天开 ...

  4. 洛谷 P4585 [FJOI2015]火星商店问题 解题报告

    P4585 [FJOI2015]火星商店问题 题目描述 火星上的一条商业街里按照商店的编号\(1,2,\dots,n\) ,依次排列着\(n\)个商店.商店里出售的琳琅满目的商品中,每种商品都用一个非 ...

  5. [FJOI2015]火星商店问题(线段树分治,可持久化,Trie树)

    [FJOI2015]火星商店问题 前天考了到线段树分治模板题,全场都切了,就我不会QAQ 于是切题无数的Tyher巨巨就告诉我:"你可以去看看火星商店问题,看了你就会了." 第一道 ...

  6. 【题解】P4585 [FJOI2015]火星商店问题(线段树套Trie树)

    [题解]P4585 [FJOI2015]火星商店问题(线段树套Trie树) 语文没学好不要写省选题面!!!! 题目大意: 有\(n\)个集合,每个集合有个任意时刻都可用的初始元素.现在有\(m\)个操 ...

  7. BZOJ4137 & 洛谷4585:[FJOI2015]火星商店问题

    https://www.lydsy.com/JudgeOnline/problem.php?id=4137 https://www.luogu.org/problemnew/show/P4585 火星 ...

  8. 【bzoj4137】[FJOI2015]火星商店问题

    *题目描述: 火星上的一条商业街里按照商店的编号1,2 ,…,n ,依次排列着n个商店.商店里出售的琳琅满目的商品中,每种商品都用一个非负整数val来标价.每个商店每天都有可能进一些新商品,其标价可能 ...

  9. 2019.01.13 bzoj4137: [FJOI2015]火星商店问题(线段树分治+可持久化01trie)

    传送门 题意:序列上有nnn个商店,有两种事件会发生: sss商店上进购标价为vvv的一个物品 求编号为[l,r][l,r][l,r]之间的位置买ddd天内新进购的所有物品与一个数xxx异或值的最大值 ...

随机推荐

  1. POJ 3735 Training little cats(矩阵快速幂)

    Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11787 Accepted: 2892 ...

  2. JUnit4.12 源码分析之Statement

    1. Statement 抽象类Statement作为命令模式的Command,只有一个方法 各种Runner作为命令模式中的Invoker,将发出各种Statement,来表示它们运行JUnit测试 ...

  3. 如何使用 libtorch 实现 VGG16 网络?

    参考地址:https://ethereon.github.io/netscope/#/preset/vgg-16 按照上面的图来写即可. 论文地址:https://arxiv.org/pdf/1409 ...

  4. Python并行编程(十一):基于进程的并行

    1.基本概念 多进程主要用multiprocessing和mpi4py这两个模块. multiprocessing是Python标准库中的模块,实现了共享内存机制,可以让运行在不同处理器核心的进程能读 ...

  5. 常用WebSite Address

    百度 魅族深度学习应用大赛 byr论坛 帖子 https://bbs.byr.cn/#!article/ML_DM/24852?p=1 百度 魅族深度学习应用大赛 官网 http://meizu.ba ...

  6. 4.ubuntu实现linux与windows的互相复制与粘贴

    为了能够在linux和windows之间直接进行互相复制粘贴,给出下面的解决办法. 系统环境: ubuntu12.04(linux), win7系统 以下指令都是在超级用户的执行权限下执行的. 要解决 ...

  7. 七、Mosquito 集群搭建

    本章主要讲述Mosquitto 集群搭建的两种方式 1.进行双服务器搭建 2.进行多服务器搭建 一.Mosquitto的分布式集群部署 如果需要做并发量很大的时候就需要考虑做集群处理,但是我在查找资料 ...

  8. Spring框架第四篇之基于注解的DI注入

    一.说明 与@Component注解功能相同,但意义不同的注解还有三个: 1)@Repository:注解在Dao实现类上 2)@Service:注解在Service实现类上 3)@Controlle ...

  9. 模块讲解----sys

    sys:跟python解释器相关的信息 #命令行参数list,第一个元素时程序本身路径 print(sys.argv) 注意:执行脚本时,可以传参数. #退出程序,正常退出时exit(0) sys.e ...

  10. DB_FILE_MULTIBLOCK_READ_COUNT对物理读和IO次数的影响

    当执行SELECT语句时,如果在内存里找不到相应的数据,就会从磁盘读取进而缓存至LRU末端(冷端),这个过程就叫物理读.当相应数据已在内存,就会逻辑读. 物理读是磁盘读,逻辑读是内存读:内存读的速度远 ...