bzoj 4137 [FJOI2015]火星商店问题——线段树分治+可持久化01trie树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4137
关于可持久化01trie树:https://www.cnblogs.com/LadyLex/p/7281110.html
看了看它的两道例题,就没写。
特殊商品可以直接用可持久化trie做。
其他部分用线段树分治。修改是单点的,询问是区间,原来想的是把询问区间定位后有 mlogn 个,在线段树的每个叶子上贡献一番;结果TLE了,因为若是在叶子处贡献,一个询问就要做 r-l+1 次。
要在线段树的每个节点上建可持久化trie,可持久化的顺序就是商店的编号;这样就能对于 mlogn 个区间,先二分找到在可持久化trie的哪一段有贡献,然后贡献给那个询问了。
做出每个节点的可持久化trie,不用trie树合并什么的,只要把当前节点表示的区间的修改排序然后一个一个加进去就行了。一共只会加 nlogn 次。
为了省时间,不用再每个节点的时候给那些修改按商店排序,而可以先按商店排好序,然后像 CDQ 分治那样稳定地把属于左边的给左边、属于右边的给右边。
在线段树的每个节点的时候,虽然可以认为同一个商店的在一棵trie树上,不同商店之间的trie树合并起来,但写的时候不能像 “if( cr==pr ) { ... sm[cr]++; ... }” 这样 “当在同一个商店的时候按普通构建trie树那样赋值” ,因为已经可持久化了, sm[cr]++ 的这个 cr 可能可以通过之前的 rt 走过来,就会出错。
注意空间不是 18*n 而是 19*n ,因为边有 18 层,节点就有 19 层。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ls Ls[cr]
#define rs Rs[cr]
#define pb push_back
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
const int N=1e5+,K=,M=19e5+;//19 not 18 for -1
int n,m,ct,sp[N],st[N],en[N],ans[N];
int tot,Ls[N<<],Rs[N<<],len;
struct Node{
int x,id,t;
bool operator< (const Node &b)const
{return id<b.id;}
}vl[N],tp[N];
struct Ques{int l,r,x;}q[N];
vector<int> vt[N<<];
namespace Tri{
int tot,c[M][],sm[M],rt[N],bin[K+];
void Init()
{bin[]=;for(int i=;i<=K;i++)bin[i]=bin[i-]<<;}
void ins(int x,int cr,int pr)
{
rt[cr]=++tot; cr=rt[cr]; pr=rt[pr];
for(int t=K;t>=;t--)
{
bool d=(x&bin[t]);
c[cr][d]=++tot; c[cr][!d]=c[pr][!d];
cr=c[cr][d]; pr=c[pr][d]; sm[cr]=sm[pr]+;
}
}
int qry(int l,int r,int x)
{
l=rt[l-]; r=rt[r]; int ret=;
for(int t=K;t>=;t--)
{
bool d=(x&bin[t]);
if(sm[c[r][!d]]-sm[c[l][!d]])
l=c[l][!d], r=c[r][!d], ret|=bin[t];
else l=c[l][d], r=c[r][d];
}
return ret;
}
}
void build(int l,int r,int cr)
{
if(l==r)return; int mid=l+r>>;
ls=++tot; build(l,mid,ls);
rs=++tot; build(mid+,r,rs);
}
void ins(int l,int r,int cr,int L,int R,int k)
{
if(l>=L&&r<=R){vt[cr].pb(k);return;}
int mid=l+r>>;
if(L<=mid)ins(l,mid,ls,L,R,k);
if(mid<R)ins(mid+,r,rs,L,R,k);
}
int fnd(int x,bool fx)
{
int l=,r=len,ret=;
while(l<=r)
{
int mid=l+r>>;
if(!fx)
{if(tp[mid].id>=x)ret=mid,r=mid-;else l=mid+;}
else
{if(tp[mid].id<=x)ret=mid,l=mid+;else r=mid-;}
}
return ret;
}
void solve(int l,int r,int cr,int L,int R)
{
for(int i=L,j=;i<=R;i++,j++)tp[j]=vl[i];//out of if()
if(vt[cr].size())
{
len=R-L+; Tri::tot=;//
for(int i=;i<=len;i++)Tri::ins(tp[i].x,i,i-);
for(int i=,j=vt[cr].size();i<j;i++)
{
int bh=vt[cr][i]; Ques k=q[bh];
int tl=fnd(k.l,), tr=fnd(k.r,);//tl,tr not l,r!!!
if(!tl||!tr||tl>tr)continue;
ans[bh]=Mx(ans[bh],Tri::qry(tl,tr,k.x));
}
}
if(l==r)return; int mid=l+r>>,p0=L-;
int tl=R-L+;
for(int i=;i<=tl;i++)if(tp[i].t<=mid)vl[++p0]=tp[i];
int p1=p0;
for(int i=;i<=tl;i++)if(tp[i].t>mid)vl[++p0]=tp[i];
solve(l,mid,ls,L,p1); solve(mid+,r,rs,p1+,R);
}
int main()
{
n=rdn();int T=rdn();
for(int i=;i<=n;i++)sp[i]=rdn();
for(int i=,op,d;i<=T;i++)
{
op=rdn();
if(!op)
{
m++; vl[m].id=rdn();vl[m].x=rdn();vl[m].t=m;
}
else
{
ct++; q[ct].l=rdn();q[ct].r=rdn();q[ct].x=rdn();
d=rdn(); st[ct]=Mx(,m-d+);en[ct]=m;
}
}
Tri::Init();
if(m)//
{
tot=;build(,m,);
for(int i=;i<=ct;i++)
if(st[i]<=en[i])ins(,m,,st[i],en[i],i);//if
sort(vl+,vl+m+); solve(,m,,,m);
}
Tri::tot=;
for(int i=;i<=n;i++)Tri::ins(sp[i],i,i-);
for(int i=;i<=ct;i++)
{
ans[i]=Mx(ans[i],Tri::qry(q[i].l,q[i].r,q[i].x));
printf("%d\n",ans[i]);
}
return ;
}
bzoj 4137 [FJOI2015]火星商店问题——线段树分治+可持久化01trie树的更多相关文章
- bzoj 4137 [FJOI2015]火星商店问题【CDQ分治+可持久化trie】
其实我不太清楚这个应该叫CDQ分治还是整体二分 参考:http://blog.csdn.net/lvzelong2014/article/details/78688727 一眼做法是线段树套可持久化t ...
- BZOJ.4137.[FJOI2015]火星商店问题(线段树分治 可持久化Trie)
BZOJ 洛谷 一直觉得自己非常zz呢.现在看来是真的=-= 注意题意描述有点问题,可以看BZOJ/洛谷讨论. 每个询问有两个限制区间,一是时间限制\([t-d+1,t]\),二是物品限制\([L,R ...
- 【题解】P4585 [FJOI2015]火星商店问题(线段树套Trie树)
[题解]P4585 [FJOI2015]火星商店问题(线段树套Trie树) 语文没学好不要写省选题面!!!! 题目大意: 有\(n\)个集合,每个集合有个任意时刻都可用的初始元素.现在有\(m\)个操 ...
- [FJOI2015]火星商店问题(线段树分治,可持久化,Trie树)
[FJOI2015]火星商店问题 前天考了到线段树分治模板题,全场都切了,就我不会QAQ 于是切题无数的Tyher巨巨就告诉我:"你可以去看看火星商店问题,看了你就会了." 第一道 ...
- 2019.01.13 bzoj4137: [FJOI2015]火星商店问题(线段树分治+可持久化01trie)
传送门 题意:序列上有nnn个商店,有两种事件会发生: sss商店上进购标价为vvv的一个物品 求编号为[l,r][l,r][l,r]之间的位置买ddd天内新进购的所有物品与一个数xxx异或值的最大值 ...
- 【洛谷P4585】 [FJOI2015]火星商店问题 线段树分治+可持久化trie
感觉这个线段树分治和整体二分几乎相同啊~ code: #include <bits/stdc++.h> #define MAX 100300 #define ll long long #d ...
- 洛谷$P4585\ [FJOI2015]$火星商店问题 线段树+$trie$树
正解:线段树+$trie$树 解题报告: 传送门$QwQ$ $umm$题目有点儿长我先写下题目大意趴$QwQ$,就说有$n$个初始均为空的集合和$m$次操作,每次操作为向某个集合内加入一个数$x$,或 ...
- 可持久化0-1Trie树
我跟可持久化数据结构杠上了 \(QwQ\) .三天模拟赛考了两次可持久化数据结构(主席树.可持久化0-1Trie树),woc. 目录: 个人理解 时空复杂度分析 例题及简析 一.个人理解 可持久化0- ...
- 【洛谷4585】[FJOI2015] 火星商店问题(线段树分治)
点此看题面 大致题意: 有\(n\)家店,每个商品有一个标价.每天,都可能有某家商店进货,也可能有某人去购物.一个人在购物时,会于编号在区间\([L_i,R_i]\)的商店里挑选一件进货\(d_i\) ...
随机推荐
- IntelliJ IDEA 自动导入包 快捷方式 关闭重复代码提示
idea可以自动优化导入包,但是有多个同名的类调用不同的包,必须自己手动Alt+Enter设置 设置idea导入包 勾选标注 1 选项,IntelliJ IDEA 将在我们书写代码的时候自动帮我们优化 ...
- OC MRC之循环引用问题(代码分析)
// // main.m // 07-循环引用 // // Created by apple on 13-8-9. // Copyright (c) 2013年 itcast. All rights ...
- 这可能是最简明扼要的 js事件冒泡机制+阻止默认事件 讲解了
哎 js事件冒泡机制和阻止冒泡 阻止默认行为好像永远也整不清楚,记了忘 忘了记...醉了 这篇文章写完以后下次再忘记 就呼自己一巴掌,忘一次一巴掌 首先要明白两个概念——事件和事件流 事件指的是用户或 ...
- cas 服务端认证流程
CAS服务端流程分析 'CAS单点登录服务器端的登录流程' -----流程的配置在/WEB-INF/login-webflow.xml文件中 <var name="credential ...
- vue + element-ui Table的数据多选,多页选择数据回显,分页记录保存选中的数据。
业务的需要:我要对与会人员勾选,记录所选的与会人员,并且点击到别的页面上时也要记录所勾选的.第一次尝试,每次点击下一页数据都会清空.然后我就去element ui官网查看了api.实现如下: 在tab ...
- 大数据技术Hadoop面试题
1. 下面哪个程序负责 HDFS 数据存储.答案C datanode a)NameNodeb)Jobtrackerc)Datanode d)secondaryNameNodee)tasktracker ...
- bootstrap-table 切换页码保留勾选的checkbox
首先该方法除了需要引入bootstrap库和bootstrap-table外,还需要引入一个工具库js:lodash.js 点我 使用时在jquery.min.js.bootstrap.min. ...
- 玩转X-CTR100 l STM32F4 l 红外遥控接收
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] X-CTR100控制器具有红外接收头,例程 ...
- android机顶盒真机调试方法
最近接触电视APP开发,之前对Android开发也不太了解还一直以为不能真机调试.最近静下心来想一想肯定能真机调试的,我是我不知道而已.现在讲述一下真机调试的步骤: 1.进入设置--关于,连续点击版本 ...
- SpringContextUtil spring上下文获取工具类
package com.midea.biz; import org.springframework.beans.BeansException; import org.springframework.c ...