[FJOI2015]火星商店问题

前天考了到线段树分治模板题,全场都切了,就我不会QAQ

于是切题无数的Tyher巨巨就告诉我:"你可以去看看火星商店问题,看了你就会了."

第一道线段树分治题,看了yyb博客,学习了一波.

其实线段树分治就是对操作的时间分治.

对线段树每个节点开一个\(vector\),把询问的区间(时间的区间)看成一段一段放到线段树的\(vector\)里面存着.

注意到修改会延续到最后一刻,所以修改只是左端点不一样而已,相当于一个后缀.

把修改按照位置排序(这个时候时间是乱序的),接着仿照线段树的形式按时间分治,在\(mid\)之前的修改,就扔到左边的数组里递归,否则就扔到右边的子树.这样就除掉了时间这一维的限制.

那么空间这一维,就用一个可持久化trie树来维护,\(r\)和\(l-1\)的对应的字典树前缀和相减就是区间的字典树.注意最开始修改要按照商店编号排序,这样按照时间分拣之后它的商店编号依然是有序的,你不妨把这些有修改的商店之间的其他商店都忽略掉,一个修改挨着一个修改地构建主席树,保证了时间复杂度.

还有一个值得注意的问题,就是当把点加到可持久化字典树里的时候,要重新从当前左端点构出字典树(相当于清空这棵可持久化字典树,假如这个询问对应的答案是当前区间之前的某次修改加入的值,那么这个询问也一定会被丢到对应的线段树节点上计算,所以不用担心之前的修改会影响询问的答案)这样可以避免撤销带来的常数.

再按照trie树找异或最大值的方法来找答案,一个询问会被放到线段树的多个节点上(会被分成很多段时间),所以答案要取\(max\).

注意线段树上的是修改时间,字典树是按照空间构建的.这个很重要,总是写着写着就忘了...

时间复杂度\(O(nlog^2n)\),线段树分治和trie树\(nlogn\),字典树\(logn\)

#include<bits/stdc++.h>
#define maxn 100005
#define mid ((l+r)>>1)
#define rc ((rt<<1)|1)
#define lc (rt<<1)
using namespace std;
int gi()
{
char c;int x,sign=1;
while((c=getchar())>'9'||c<'0')if(c=='-')sign=-1;
x=c-'0';while((c=getchar())>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0';
return x*sign;
}
int n,m,cnt1,cnt2,tot,top;
int rt[maxn],ans[maxn],st[maxn];
int ch[maxn*20][2],sz[maxn*20];
vector<int> a[maxn];
struct guest{int l,r,L,R,x;}p[maxn];
struct buy{int s,v,t;}q[maxn],t1[maxn],t2[maxn];
bool cmp(const buy x,const buy y){return x.s<y.s;}
void insert(int &x,int u,int w)
{
int now;now=x=++tot;
for(int i=17;i>=0;i--)
{
bool d=w&(1<<i);
ch[now][d^1]=ch[u][d^1];ch[now][d]=++tot;
now=ch[now][d];u=ch[u][d];
sz[now]=sz[u]+1;
}
}
int query(int l,int r,int w)
{
int res=0;
for(int i=17;i>=0;i--)
{
bool d=w&(1<<i);
if(sz[ch[r][d^1]]-sz[ch[l][d^1]]>0)
l=ch[l][d^1],r=ch[r][d^1],res+=(1<<i);
else l=ch[l][d],r=ch[r][d];
}
return res;
}
void update(int rt,int l,int r,int L,int R,int x)
{
if(L>R||r<L||l>R)return ;
if(L<=l&&r<=R){a[rt].push_back(x);return;}
update(lc,l,mid,L,R,x);update(rc,mid+1,r,L,R,x);
}
void calc(int x,int L,int R)
{
top=tot=0;
for(int i=L;i<=R;i++)
{
st[++top]=q[i].s;
insert(rt[top],rt[top-1],q[i].v);
}
for(int i=0,sz=a[x].size();i<sz;i++)
{
int k=a[x][i],t;
int l=upper_bound(st+1,st+1+top,p[k].l-1)-st-1;
int r=upper_bound(st+1,st+1+top,p[k].r)-st-1;
ans[k]=max(ans[k],t=query(rt[l],rt[r],p[k].x));
//cout<<x<<" "<<k<<" "<<t<<endl;
}
}
void divide(int rt,int l,int r,int L,int R)//按时间分治
{
if(L>R)return;
int cn1=0,cn2=0;
calc(rt,L,R);
if(l==r)return;
for(int i=L;i<=R;i++)//修改的区间右端点都是cnt1,相当于影响到之后的时间
if(q[i].t<=mid)t1[++cn1]=q[i];
else t2[++cn2]=q[i];
for(int i=1;i<=cn1;i++)q[i+L-1]=t1[i];//左端点在mid左边的放在左区间
for(int i=1;i<=cn2;i++)q[i+L-1+cn1]=t2[i];//否则放右边
divide(lc,l,mid,L,L+cn1-1);
divide(rc,mid+1,r,L+cn1,R);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)insert(rt[i],rt[i-1],gi());
for(int i=1,ty,l,r,x,d,s,v;i<=m;i++)
{
ty=gi();
if(!ty)s=gi(),v=gi(),q[++cnt1]=(buy){s,v,cnt1};//起点,价格,时间
else
{
l=gi(),r=gi(),x=gi(),d=gi();
ans[++cnt2]=query(rt[l-1],rt[r],x);
p[cnt2]=(guest){l,r,max(1,cnt1-d+1),cnt1,x};
//商店左端点,商店右端点,开始时间,结束时间,喜好密码
}
}
for(int i=1;i<=cnt2;i++)update(1,1,cnt1,p[i].L,p[i].R,i);
sort(q+1,q+1+cnt1,cmp);//按照商店编号排序
divide(1,1,cnt1,1,cnt1);
for(int i=1;i<=cnt2;i++)printf("%d\n",ans[i]);
return 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. 【洛谷】P4585 [FJOI2015]火星商店问题

    题解 题目太丧,OJ太没有良心,我永远喜欢LOJ! (TLE报成RE,垃圾洛谷,我永远喜欢LOJ) 好的,平复一下我debug了一上午崩溃的心态= =,写一写这道题的题解 把所有限制去掉,给出一个值, ...

随机推荐

  1. [记录]python的简单协程框架(回调+时间循环+select)

    # -*- coding: utf-8 -*- # @Time : 2018/12/15 18:55 # @File : coroutine.py #一个简单的 Coroutine 框架 import ...

  2. VNC服务配置

    Windows通过VNC远程桌面访问Ubuntu设备:一个WIN7的机器,一个系统为Ubuntu的机器 (二者可以均可为虚拟机或实体机) 目的:在Windows系统上通过VNC远程访问Ubuntu. ...

  3. [leetcode ]429. N-ary Tree Level Order Traversale (easy)

    原题 思路: bfs,每一层遍历一次加到一个vector,同时把该点的子元素加到queue中. class Solution { public: vector<vector<int> ...

  4. 使用java Apache poi 根据word模板生成word报表

    项目开发过程中,客户提出一堆导出报表的需求,需要导出word格式,页眉还需要加上客户公司的logo,试了几种方案,最后选择了用 Apache poi 加上自定义标签的方式实现. 目前功能还比较简单,一 ...

  5. .gitignore文件我自己常用的配置

    我项目中一般不需要上传到git服务器上的有 .idea ------.idea目录 .mvn ------.mvn目录 .iml mvnw mvnw.cmd logs/ --- 我生成的日志文件目录 ...

  6. paddlepaddle实现猫狗分类

    目录 1.预备工作 1.1 数据集准备 1.2 数据预处理 2.训练 2.1 模型 2.2 定义训练 2.3 训练 3.预测 4.参考文献 声明:这是我的个人学习笔记,大佬可以点评,指导,不喜勿喷.实 ...

  7. web设计_2_灵活的文字

    最佳设计:可以让用户自由控制任何页面的文字大小. 浏览器中用户都是可以自定义默认的文字大小的,如果使用 px,用户自行在浏览器设置中改变了文字大小后,网页上是不会变化的.我们不能排除视障用户(如近视) ...

  8. PHP与ECMAScript_7_流程控制

      PHP ECMAScript 顺序结构 默认从上到下依次执行 默认从上到下依次执行 分支结构 if  / switch if   /  switch 循环结构 for / while / do-w ...

  9. AbstractCollection

    概述 这个类提供了实现Collection接口的骨架,来最小化实现此接口所做的工作. 要实现一个不可修改的 collection,编程人员只需扩展此类,并提供 iterator 和 size 方法的实 ...

  10. 走近OPENCV // opencv 2.4.9+vs2013配置

    一直很懒去配opencv,这几周忍不了终于抽空来配了一下环境... 用的是旧版opencv2.4系列,最新到3.0了,之后再看看教程不知道有什么特别大的区别. (FF14国服没有4.0 // 8.19 ...