2019.01.13 bzoj4137: [FJOI2015]火星商店问题(线段树分治+可持久化01trie)
传送门
题意:序列上有nnn个商店,有两种事件会发生:
- sss商店上进购标价为vvv的一个物品
- 求编号为[l,r][l,r][l,r]之间的位置买ddd天内新进购的所有物品与一个数xxx异或值的最大值。
每个位置都有一种物品每天会新进购(最开始会给出)。
思路:
第一眼显然的线段树套可持久化01trie 恭喜MLE走人
然后发现每个人的询问可以放到按时间建出的线段树上,这个不就可以线段树分治离线处理了吗。
于是把每天进购的物品排个序下放,每一层线段树用一个可持久化01trie来统计答案即可(注意这个并不是线段树和可持久化01trie套在一起)
代码:
#include<bits/stdc++.h>
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (l+r>>1)
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
const int N=1e5+5,P=17;
int n,m,stk[N],rt[N],siz[N*20],son[N*20][2],top=0,tot=0,sig=0,ans[N],cnt=0;
vector<int>e[N],qry[N<<2];
struct Query{int l,r,dl,dr,v;}pd[N];
struct UPD{int s,v,d;}upd[N],t1[N],t2[N];
inline void insert(int&p,int last,int val){
int o=p=++tot;
for(ri i=17;~i;--i){
int tmp=(val>>i)&1;
son[o][tmp]=++tot,son[o][tmp^1]=son[last][tmp^1];
o=son[o][tmp],last=son[last][tmp],siz[o]=siz[last]+1;
}
}
inline int query(int ql,int qr,int val){
int ret=0;
for(ri i=17;~i;--i){
int tmp=(val>>i)&1;
if(siz[son[qr][tmp^1]]^siz[son[ql][tmp^1]])ret|=(1<<i),ql=son[ql][tmp^1],qr=son[qr][tmp^1];
else ql=son[ql][tmp],qr=son[qr][tmp];
}
return ret;
}
inline void update(int p,int l,int r,int ql,int qr,int v){
if(ql>r||qr<l||ql>qr)return;
if(ql<=l&&r<=qr){qry[p].push_back(v);return;}
if(qr<=mid)update(lc,l,mid,ql,qr,v);
else if(ql>mid)update(rc,mid+1,r,ql,qr,v);
else update(lc,l,mid,ql,mid,v),update(rc,mid+1,r,ql,qr,v);
}
inline void calc(int p,int l,int r){
tot=top=0;
for(ri i=l;i<=r;++i){
int s=upd[i].s,v=upd[i].v;
stk[++top]=s,insert(rt[top],rt[top-1],v);
}
for(ri i=0;i<qry[p].size();++i){
int x=qry[p][i];
int ql=upper_bound(stk+1,stk+top+1,pd[x].l-1)-stk-1;
int qr=upper_bound(stk+1,stk+top+1,pd[x].r)-stk-1;
ans[x]=max(ans[x],query(rt[ql],rt[qr],pd[x].v));
}
}
inline void solve(int p,int l,int r,int ql,int qr){
if(ql>qr)return;
calc(p,ql,qr);
if(l==r)return;
int hd1=0,hd2=0;
for(ri i=ql;i<=qr;++i)if(upd[i].d<=mid)t1[++hd1]=upd[i];else t2[++hd2]=upd[i];
for(ri i=1;i<=hd1;++i)upd[ql+i-1]=t1[i];
for(ri i=1;i<=hd2;++i)upd[ql+hd1+i-1]=t2[i];
solve(lc,l,mid,ql,ql+hd1-1),solve(rc,mid+1,r,ql+hd1,qr);
}
inline bool cmp(const UPD&a,const UPD&b){return a.s<b.s;}
int main(){
n=read(),m=read();
for(ri i=1;i<=n;++i)insert(rt[i],rt[i-1],read());
for(ri i=1,op,ql,qr,x,s,d,v;i<=m;++i){
op=read();
if(op){
ql=read(),qr=read(),x=read(),d=read();
ans[++sig]=query(rt[ql-1],rt[qr],x);
pd[sig]=(Query){ql,qr,max(1,cnt-d+1),cnt,x};
}
else s=read(),v=read(),upd[++cnt]=(UPD){s,v,cnt};
}
for(ri i=1;i<=sig;++i)update(1,1,cnt,pd[i].dl,pd[i].dr,i);
sort(upd+1,upd+cnt+1,cmp);
solve(1,1,cnt,1,cnt);
for(ri i=1;i<=sig;++i)cout<<ans[i]<<'\n';
return 0;
}
2019.01.13 bzoj4137: [FJOI2015]火星商店问题(线段树分治+可持久化01trie)的更多相关文章
- bzoj 4137 [FJOI2015]火星商店问题——线段树分治+可持久化01trie树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4137 关于可持久化01trie树:https://www.cnblogs.com/LadyL ...
- [FJOI2015]火星商店问题(线段树分治,可持久化,Trie树)
[FJOI2015]火星商店问题 前天考了到线段树分治模板题,全场都切了,就我不会QAQ 于是切题无数的Tyher巨巨就告诉我:"你可以去看看火星商店问题,看了你就会了." 第一道 ...
- BZOJ.4137.[FJOI2015]火星商店问题(线段树分治 可持久化Trie)
BZOJ 洛谷 一直觉得自己非常zz呢.现在看来是真的=-= 注意题意描述有点问题,可以看BZOJ/洛谷讨论. 每个询问有两个限制区间,一是时间限制\([t-d+1,t]\),二是物品限制\([L,R ...
- 【洛谷P4585】 [FJOI2015]火星商店问题 线段树分治+可持久化trie
感觉这个线段树分治和整体二分几乎相同啊~ code: #include <bits/stdc++.h> #define MAX 100300 #define ll long long #d ...
- 【题解】P4585 [FJOI2015]火星商店问题(线段树套Trie树)
[题解]P4585 [FJOI2015]火星商店问题(线段树套Trie树) 语文没学好不要写省选题面!!!! 题目大意: 有\(n\)个集合,每个集合有个任意时刻都可用的初始元素.现在有\(m\)个操 ...
- bzoj 4137 [FJOI2015]火星商店问题【CDQ分治+可持久化trie】
其实我不太清楚这个应该叫CDQ分治还是整体二分 参考:http://blog.csdn.net/lvzelong2014/article/details/78688727 一眼做法是线段树套可持久化t ...
- 洛谷$P4585\ [FJOI2015]$火星商店问题 线段树+$trie$树
正解:线段树+$trie$树 解题报告: 传送门$QwQ$ $umm$题目有点儿长我先写下题目大意趴$QwQ$,就说有$n$个初始均为空的集合和$m$次操作,每次操作为向某个集合内加入一个数$x$,或 ...
- [FJOI2015]火星商店问题(线段树分治+可持久化Trie)
重新写一年前抄题解的那题,当时我啥都不会只是Ctrl+C,Ctrl+V写过的题,今天重新写一遍. 题解: 不会线段树分治,还是学一下这东西吧,这是我的第一道线段树分治. 首先对于特殊商品,可以直接可持 ...
- bzoj4137 [FJOI2015]火星商店问题
比较容易想到的做法是线段树套字典树,修改操作时在字典树上经过的节点维护一个最近被访问过的时间,这样询问操作只经过满足时间条件的节点,时间复杂度O(NlogN^2)但是因为线段树每个节点都要套个字典树, ...
随机推荐
- nodejs中.npmrc文件的内容
. nodejs安装后,使用npm安装模块的时候我出现了一个错误. getaddrinfo ENOTFOUND xxx 主要是这个配置文件的问题.搞不清楚.直接打开把文件内容删除变成 npmrc文件内 ...
- Jmeter录制APP脚本
启动 jmeter.bat 在 Test Plan 下 添加 Thread Group 在 WorkBench 下 添加 HTTP(S) Test Script Recorder: 配置 Global ...
- Intellij创建简单Springboot项目
Intellij创建简单Springboot项目 第一步:选择创建新项目——file-new-project 第二步:选择项目类型——Spring Initializr-next 第三步:输入项目信息 ...
- ubuntu系列-很好用的截图工具shutter
直接在ubuntu软件市场中搜索“shutter”下载即可
- json的内容回顾
复习一下json这个模块 import json s = '{"name":"cui","age":12}' # 这里外部必须是单引号,内部 ...
- python颜色及背景
linux终端中的颜色是用转义序列控制的,转义序列是以ESC开头,可以用\033完成相同的工作(ESC的ASCII码用十进制表示就是27,等于用八进制表示的33). 书写格式,和相关说明如下: 1 2 ...
- git bash 基本命令
1.打开git bash界面后,进入某个目录下时时,可以使用cd 命令,cd时change directory的简写,表示改变目录,比如,想切换到某个盘符下,可以使用cd g:,则会进入到g盘路径下, ...
- 在微信小程序中调用本地接口
1.点击详情,并勾选项目设置中最后一行. 2.用小程序请求本地的后台服务接口 wx.request({ url: 'http://localhost:8090/DemoProject/myTest.d ...
- Non-negative Integers without Consecutive Ones
n位二进制,求不包含连续1的二进制(n位)数字个数. http://www.geeksforgeeks.org/count-number-binary-strings-without-consecut ...
- poj 2777(线段树+lazy思想) 小小粉刷匠
http://poj.org/problem?id=2777 题目大意 涂颜色,输入长度,颜色总数,涂颜色次数,初始颜色都为1,然后当输入为C的时候将x到y涂为颜色z,输入为Q的时候输出x到y的颜色总 ...