BZOJ.4137.[FJOI2015]火星商店问题(线段树分治 可持久化Trie)
一直觉得自己非常zz呢。现在看来是真的=-=
注意题意描述有点问题,可以看BZOJ/洛谷讨论。
每个询问有两个限制区间,一是时间限制\([t-d+1,t]\),二是物品限制\([L,R]\)。
每个物品都是在一个时间点发生的(并不是区间,我竟然一直没想通= =)。那么就可以按时间线段树分治了。
把每个询问按时间区间放到线段树对应节点上。那么在每个节点处,把时间点在该区间内的物品,按编号从小到大插入到可持久化\(Trie\)里,就可以解决这个节点上的询问了。
排序可以在最开始将物品按编号排序,分治时直接根据时间点划分到左右两个子区间继续处理。
//39092kb 3156ms
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <algorithm>
#define gc() getchar()
#define BIT 16
#define MAXIN 500000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5;
int root[N],Ans[N];
char IN[MAXIN],*SS=IN,*TT=IN;
struct OPT
{
int t,id,v;
bool operator <(const OPT &x)const
{
return id<x.id;
}
}opt[N],tmp1[N],tmp2[N];
struct Quries
{
int l,r,tl,tr,v;
}q[N];
struct TRIE
{
#define S N*(BIT+2)
int tot,son[S][2],sz[S];
#undef S
void Insert(int &rt,int y,int v)
{
int x=rt=++tot;
for(int i=BIT,c; ~i; --i)
c=v>>i&1, son[x][c^1]=son[y][c^1], x=son[x][c]=++tot, y=son[y][c], sz[x]=sz[y]+1;
}
int Query(int x,int y,int v)//y-x
{
int res=0;
for(int i=BIT,c; ~i; --i)
{
c=(v>>i&1)^1;
if(sz[son[y][c]]-sz[son[x][c]]>0) res|=1<<i;
else c^=1;
x=son[x][c], y=son[y][c];
}
return res;
}
}Trie;
struct Segment_Tree
{
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
#define S N<<2
int A[N];
std::vector<int> vec[S];
#undef S
void Modify(int l,int r,int rt,int L,int R,int v)
{
if(L<=l && r<=R) {vec[rt].push_back(v); return;}
int m=l+r>>1;
if(L<=m) Modify(lson,L,R,v);
if(m<R) Modify(rson,L,R,v);
}
inline int Find(int x,int r)
{
int l=1,mid,ans=0;
while(l<=r)
if(A[mid=l+r>>1]<=x) ans=mid,l=mid+1;
else r=mid-1;
return ans;
}
void Solve(int L,int R,const std::vector<int> &v)
{
Trie.tot=0; int t=0;
for(int i=L; i<=R; ++i) A[++t]=opt[i].id, Trie.Insert(root[t],root[t-1],opt[i].v);
for(int i=0,lim=v.size(),id; i<lim; ++i)
{
const Quries &q=::q[id=v[i]];
Ans[id]=std::max(Ans[id],Trie.Query(root[Find(q.l-1,t)],root[Find(q.r,t)],q.v));
}
}
void DFS(int l,int r,int rt,int L,int R)
{
if(L>R) return;
if(vec[rt].size()) Solve(L,R,vec[rt]);
if(l==r) return;
int m=l+r>>1,t1=0,t2=0;
for(int i=L; i<=R; ++i) opt[i].t<=m?(tmp1[t1++]=opt[i],0):(tmp2[t2++]=opt[i],0);
for(int i=0,p=L; i<t1; opt[p++]=tmp1[i++]);
for(int i=0,p=L+t1; i<t2; opt[p++]=tmp2[i++]);
DFS(lson,L,L+t1-1), DFS(rson,L+t1,R);
}
}T;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
int main()
{
const int n=read(),m=read();
for(int i=1; i<=n; ++i) Trie.Insert(root[i],root[i-1],read());
int tot=0,cnt=0;
for(int i=1,l,r,v; i<=m; ++i)
if(!read()) ++tot, opt[tot]=(OPT){tot,read(),read()};
else l=read(),r=read(),v=read(),Ans[++cnt]=Trie.Query(root[l-1],root[r],v), q[cnt]=(Quries){l,r,std::max(tot-read()+1,1),tot,v};
std::sort(opt+1,opt+1+tot);
for(int i=1; i<=cnt; ++i) if(q[i].tl<=q[i].tr) T.Modify(1,tot,1,q[i].tl,q[i].tr,i);
T.DFS(1,tot,1,1,tot);
for(int i=1; i<=cnt; ++i) printf("%d\n",Ans[i]);
return 0;
}
BZOJ.4137.[FJOI2015]火星商店问题(线段树分治 可持久化Trie)的更多相关文章
- bzoj 4137 [FJOI2015]火星商店问题——线段树分治+可持久化01trie树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4137 关于可持久化01trie树:https://www.cnblogs.com/LadyL ...
- bzoj 4137 [FJOI2015]火星商店问题【CDQ分治+可持久化trie】
其实我不太清楚这个应该叫CDQ分治还是整体二分 参考:http://blog.csdn.net/lvzelong2014/article/details/78688727 一眼做法是线段树套可持久化t ...
- [FJOI2015]火星商店问题(线段树分治,可持久化,Trie树)
[FJOI2015]火星商店问题 前天考了到线段树分治模板题,全场都切了,就我不会QAQ 于是切题无数的Tyher巨巨就告诉我:"你可以去看看火星商店问题,看了你就会了." 第一道 ...
- 【洛谷P4585】 [FJOI2015]火星商店问题 线段树分治+可持久化trie
感觉这个线段树分治和整体二分几乎相同啊~ code: #include <bits/stdc++.h> #define MAX 100300 #define ll long long #d ...
- 【题解】P4585 [FJOI2015]火星商店问题(线段树套Trie树)
[题解]P4585 [FJOI2015]火星商店问题(线段树套Trie树) 语文没学好不要写省选题面!!!! 题目大意: 有\(n\)个集合,每个集合有个任意时刻都可用的初始元素.现在有\(m\)个操 ...
- [FJOI2015]火星商店问题(线段树分治+可持久化Trie)
重新写一年前抄题解的那题,当时我啥都不会只是Ctrl+C,Ctrl+V写过的题,今天重新写一遍. 题解: 不会线段树分治,还是学一下这东西吧,这是我的第一道线段树分治. 首先对于特殊商品,可以直接可持 ...
- 洛谷$P4585\ [FJOI2015]$火星商店问题 线段树+$trie$树
正解:线段树+$trie$树 解题报告: 传送门$QwQ$ $umm$题目有点儿长我先写下题目大意趴$QwQ$,就说有$n$个初始均为空的集合和$m$次操作,每次操作为向某个集合内加入一个数$x$,或 ...
- 2019.01.13 bzoj4137: [FJOI2015]火星商店问题(线段树分治+可持久化01trie)
传送门 题意:序列上有nnn个商店,有两种事件会发生: sss商店上进购标价为vvv的一个物品 求编号为[l,r][l,r][l,r]之间的位置买ddd天内新进购的所有物品与一个数xxx异或值的最大值 ...
- 【洛谷4585】[FJOI2015] 火星商店问题(线段树分治)
点此看题面 大致题意: 有\(n\)家店,每个商品有一个标价.每天,都可能有某家商店进货,也可能有某人去购物.一个人在购物时,会于编号在区间\([L_i,R_i]\)的商店里挑选一件进货\(d_i\) ...
随机推荐
- uCosII中的任务
任务基本概念 任务是一个接受操作系统管理的独立运行单元,在uCosII中类似与普通平台上的main()函数,需要自己来保护其因调用或中断二产生的断点,所以需要一个自己的私有堆栈,即任务堆栈: 任务有两 ...
- CSS3 Background-clip
上一节在<CSS3 background-size>详细的介绍了CSS3为background新增属性之一,今天和大家一起来学习CSS3中有关于Background的第二新属性Backgr ...
- Exp2 后门原理与实践 20164314 郭浏聿
1.实践内容 (1)使用nc实现win,Linux间的后门连接. 热身 (2)使用netcat获取主机操作Shell,cron启动. (3)使用socat获取主机操作Shell, 任务计划启动. (4 ...
- Ubuntu 18.04 记录
登录后死机,关机时死机的解决方法 更新内核并安装 Nvidia 显卡驱动可解决. 在内核更新为 4.15.18,Nvidia 显卡驱动为 390 时,问题解决. 使用 LiveCD 启动,然后 mou ...
- P5300 [GXOI/GZOI2019]与或和
题目地址:P5300 [GXOI/GZOI2019]与或和 考虑按位计算贡献 对于 AND 运算,只有全 \(1\) 子矩阵才会有贡献 对于 OR 运算,所以非全 \(0\) 子矩阵均有贡献 如果求一 ...
- Maven - <Profile>详解
转载自:https://www.cnblogs.com/wxgblogs/p/6696229.html Profile能让你为一个特殊的环境自定义一个特殊的构建:profile使得不同环境间构建的可移 ...
- 区块链之智能合约 solidity踩坑 --上篇
概述 最近在写合约时遇到一些坑,做一下总结: 介绍主要分一下三个方面: 对区块链的简单描述 结合业务场景,编写简单智能合约,时遇到的坑(上篇) assembly 的使用说明(下篇) 正文 进入正题之前 ...
- 机器学习基石8-Noise and Error
注: 文章中所有的图片均来自台湾大学林轩田<机器学习基石>课程. 笔记原作者:红色石头 微信公众号:AI有道 上一节课,我们主要介绍了VC Dimension的概念.如果Hypothese ...
- 某喷码机品牌U盘存储的配置文件简记
U盘下的 KadexMicro 文件夹是喷码机生成的. 其配置文件存储在如上图位置,后缀 .mjt 实为 xml 文件. 内容如: <?xml version="1.0" e ...
- 帆软报表(finereport)间格运算常用公式
1.1在C3(占比)单元格中直接使用占比公式:=PROPORTION(B3):占比:当前值占总值的比例 1.2 计组内占比注:C2[!0]{A2=$A2},表示C2扩展出来地区相同的单元格.sum(C ...