BZOJ

洛谷

一直觉得自己非常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)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 【转载】C++ STL快速入门

    https://www.cnblogs.com/skyfsm/p/6934246.html

  2. JS 两个对象数组合并并去重

    JS两个对象数组合并并去重 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  3. mysql—常用查询语句总结

    关于MySQL常用的查询语句 一查询数值型数据: ; 查询谓词:>,=,<,<>,!=,!>,!<,=>,=< 二查询字符串 SELECT * FROM ...

  4. HDU-1398 Square Coins(生成函数)

    题意 与$hdu1028$类似,只不过可用的数字都是平方数. 思路 类似的思路,注意下细节. 代码 #include <bits/stdc++.h> #define DBG(x) cerr ...

  5. Android Studio安装后配置默认新工程目录以及.gradle,.android,.m2和system,config目录

    关于在哪里设置:以下所有设置都是在没有打开工程的前提下设置的, Configure > Settings 如图: 不要使用 Configure > Project Defaults> ...

  6. vue.js学习系列-第一篇

    VUE系列一 简介    vue是一个兴起的前端js库,是一个精简的MVVM.从技术角度讲,Vue.js专注于 MVVM 模型的 ViewModel 层.它通过双向数据绑定把 View 层和 Mode ...

  7. TypeScript 错误property does not exist on type Object

    TypeScript 错误property does not exist on type Object 在TypeScript中如果按JS的方式去获取对象属性,有时会提示形如Property 'val ...

  8. mac 安装和使用MongoDB

    安装 尝试一:手动命令安装尝试二:采用Homebrew尝试三:下载安装包使用安装尝试一:手动命令安装按照官网https://docs.mongodb.com/manual/tutorial/insta ...

  9. Oracle XMLTYPE数据类型创建及插入

    --1.创建xml表Create TABLE testxml2(id NUMBER,data XMLTYPE); --2.插入数据--1)创建目录 CREATE or replace DIRECTOR ...

  10. C# Bitmap生成base64码

    public static string ImgToBase64String(Bitmap bmp) { try { MemoryStream ms = new MemoryStream(); bmp ...