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

题面

洛谷

BZOJ权限题

题解

显然可以树套树,外层线段树,内层可持久化Trie来做。

所以我们需要更加优美的做法。——线段树分治。

什么叫做线段树分治呢?

我们发现每次询问都是区间的形式,看到区间我们就可以想到线段数。

我们接着观察,发现了两个特点:询问是区间,加入新数是单点。

那么我们对于单点构建线段树,在本题中这个单点是按照时间顺序构建的。

所以每次询问在不考虑区间的情况下对应的时间是唯一的。

所以把每次询问暴力放到线段树的每个节点上,用\(vector\)记录。

那么,我们\(dfs\)遍历整棵线段树,

我们发现每个询问已经不用再考虑时间的问题,而只需要考虑区间的问题。

那么对于当前线段树时间区间的所有插入操作按照区间排序。

构建可持久化\(Trie\)直接查答案就好了。

代码应该注释海星。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 100100
#define lson (now<<1)
#define rson (now<<1|1)
#define pb(x) push_back(x)
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Buy{int s,v,t;}q[MAX],tmp1[MAX],tmp2[MAX];
struct Ask{int l,r,tl,tr,x;}p[MAX];
bool cmp(Buy a,Buy b){return a.s<b.s;}
int rt[MAX];
namespace Trie//可持久化Trie
{
struct Trie{int son[2],w;}t[MAX<<5];
int tot,rt[MAX];
void insert(int &x,int ff,int w,int now)
{
t[x=++tot]=t[ff];t[x].w++;
if(now==-1)return;
bool c=w&(1<<now);
insert(t[x].son[c],t[ff].son[c],w,now-1);
}
int Query(int l,int r,int w,int now)
{
if(now==-1)return 0;
bool c=w&(1<<now);
int tmp=t[t[r].son[c^1]].w-t[t[l].son[c^1]].w;
if(tmp)return Query(t[l].son[c^1],t[r].son[c^1],w,now-1)+(1<<now);
else return Query(t[l].son[c],t[r].son[c],w,now-1);
}
}
int n,m,ans[MAX];
vector<int> seg[MAX<<2];
int cnt1,cnt2;
//对于线段树的每个节点插入对应的询问
//线段树的每个节点代表着一个购买的时间
//然后对于每个线段树上的节点,维护哪些询问出现在了这些时间之中
//所以对于一个节点维护一个vector,将出现在这段时间中的询问放入vector中
void Modify(int now,int l,int r,int L,int R,int x)
{
if(L>R)return;
if(L<=l&&r<=R){seg[now].pb(x);return;}
int mid=(l+r)>>1;
if(L<=mid)Modify(lson,l,mid,L,R,x);
if(R>mid)Modify(rson,mid+1,r,L,R,x);
}
int S[MAX],top;
//对于当前节点计算在区间内的答案
//考虑如何计算贡献,因为保证了当前节点内的所有询问的时间
//所以只需要考虑区间的问题了,因此按照区间维护可持久化Trie即可
int Binary(int x)
{
int l=1,r=top,ret=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(S[mid]<=x)ret=mid,l=mid+1;
else r=mid-1;
}
return ret;
}
void Calc(int now,int L,int R)
{
top=Trie::tot=0;
for(int i=L;i<=R;++i)
{
S[++top]=q[i].s;
Trie::insert(rt[top],rt[top-1],q[i].v,17);
}
for(int i=0,len=seg[now].size();i<len;++i)
{
int k=seg[now][i];
int l=Binary(p[k].l-1),r=Binary(p[k].r);
ans[k]=max(ans[k],Trie::Query(rt[l],rt[r],p[k].x,17));
}
}
void Divide(int now,int l,int r,int L,int R)
{
if(L>R)return;int mid=(l+r)>>1,t1=0,t2=0;
Calc(now,L,R);if(l==r)return;
for(int i=L;i<=R;++i)
if(q[i].t<=mid)tmp1[++t1]=q[i];
else tmp2[++t2]=q[i];
for(int i=1;i<=t1;++i)q[i+L-1]=tmp1[i];
for(int i=1;i<=t2;++i)q[i+L-1+t1]=tmp2[i];
Divide(lson,l,mid,L,L+t1-1);
Divide(rson,mid+1,r,L+t1,R);
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;++i)Trie::insert(rt[i],rt[i-1],read(),17);
for(int i=1;i<=m;++i)
{
int opt=read();
if(!opt)
{
int s=read(),v=read();++cnt1;
q[cnt1]=(Buy){s,v,cnt1};
}
else
{
int l=read(),r=read(),x=read(),d=read();
ans[++cnt2]=Trie::Query(rt[l-1],rt[r],x,17);
p[cnt2]=(Ask){l,r,max(1,cnt1-d+1),cnt1,x};
}
}
for(int i=1;i<=cnt2;++i)Modify(1,1,cnt1,p[i].tl,p[i].tr,i);
sort(&q[1],&q[cnt1+1],cmp);//按照商店的编号依次插入所有物品
Divide(1,1,cnt1,1,cnt1);
for(int i=1;i<=cnt2;++i)printf("%d\n",ans[i]);
return 0;
}

【BZOJ4137】火星商店问题(线段树分治,可持久化Trie)的更多相关文章

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

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

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

    BZOJ 洛谷 一直觉得自己非常zz呢.现在看来是真的=-= 注意题意描述有点问题,可以看BZOJ/洛谷讨论. 每个询问有两个限制区间,一是时间限制\([t-d+1,t]\),二是物品限制\([L,R ...

  3. 【洛谷P4585】 [FJOI2015]火星商店问题 线段树分治+可持久化trie

    感觉这个线段树分治和整体二分几乎相同啊~ code: #include <bits/stdc++.h> #define MAX 100300 #define ll long long #d ...

  4. bzoj 4137 [FJOI2015]火星商店问题——线段树分治+可持久化01trie树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4137 关于可持久化01trie树:https://www.cnblogs.com/LadyL ...

  5. bzoj 4137 [FJOI2015]火星商店问题【CDQ分治+可持久化trie】

    其实我不太清楚这个应该叫CDQ分治还是整体二分 参考:http://blog.csdn.net/lvzelong2014/article/details/78688727 一眼做法是线段树套可持久化t ...

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

    重新写一年前抄题解的那题,当时我啥都不会只是Ctrl+C,Ctrl+V写过的题,今天重新写一遍. 题解: 不会线段树分治,还是学一下这东西吧,这是我的第一道线段树分治. 首先对于特殊商品,可以直接可持 ...

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

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

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

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

  9. 洛谷$P4585\ [FJOI2015]$火星商店问题 线段树+$trie$树

    正解:线段树+$trie$树 解题报告: 传送门$QwQ$ $umm$题目有点儿长我先写下题目大意趴$QwQ$,就说有$n$个初始均为空的集合和$m$次操作,每次操作为向某个集合内加入一个数$x$,或 ...

  10. 【洛谷4585】[FJOI2015] 火星商店问题(线段树分治)

    点此看题面 大致题意: 有\(n\)家店,每个商品有一个标价.每天,都可能有某家商店进货,也可能有某人去购物.一个人在购物时,会于编号在区间\([L_i,R_i]\)的商店里挑选一件进货\(d_i\) ...

随机推荐

  1. Ajax在Django中的应用

    一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传 ...

  2. 使用T4模板报错:“正在编译转换;当前上下文中不存在名称Host”

             用T4模板生成多个文件的实体时,有一句代码是这样的 string curPath = Path.GetDirectoryName(Host.TemplateFile);       ...

  3. LUA对象

    Rectangle = {width = , height = , area = }; function Rectangle:new(o, width, height) o = o or {}; se ...

  4. SQL Server 2008 R2 链接 Oracle 10g

    首先sqlserver 链接oracle可以通过两个访问接口: “MSDAORA” 和“OraOLEDB.Oracle” 1.“MSDAORA”访问接口是由Microsoft OLE DB Provi ...

  5. TeamViewer卡在正在初始化显示参数

    在windows的mstsc远程桌面中打开teamviewer,远程桌面开着的时候可以连接teamviewer,但是当我断开mstsc之后,再用teamviewer连就连接不上了,一直都是正在初始化显 ...

  6. activeX 打包

    原文 http://www.docin.com/p-409284488.html CAB打包文档说明 文档目的 本文档的目的在于说明将ocx和dll以及相关的文件打包成一个CAB包,以便在网页下调用o ...

  7. HTML5 + CSS3 实现地球绕太阳公转

    使用的是正面视角,主要是用 HTML5 + CSS3 来实现,JS只是用来画图. test.html: <!DOCTYPE html> <html> <head> ...

  8. Siki_Unity_2-7_Stealth秘密行动

    Unity 2-7 Stealth秘密行动 Abstract:向量运算:Animation动画:Navigation寻路系统:Mecanim动画系统 任务1&2&3:游戏介绍 & ...

  9. 如何隐藏掉SQL Server中自带系统数据库,数据表,存储过程等显示文件,只显示用户的数据库,数据表等文件

    企业管理器了,---->   编辑该数据库的注册属性--->“常规”属性页下面-->“显示系统数据库和系统对象”的选项去掉

  10. 点滴拾遗 - 自定义 Format 控制 String.Format 行为

    点击下载示例代码 String.Format 一重载方法的签名如下 public static string Format( IFormatProvider provider, string form ...