其实我不太清楚这个应该叫CDQ分治还是整体二分

参考:http://blog.csdn.net/lvzelong2014/article/details/78688727

一眼做法是线段树套可持久化trie,但是会MLE+TLE

考虑用CDQ推掉线段树

首先对于没有时间限制的商品建一棵可持久化trie,先更新一遍ans。

然后对于询问和修改分别处理,多记录一维时间,把修改操作按照商店编号排序,对于询问操作的d,改为在时间维度上的一段区间[s,t]

对时间维进行二分,模拟线段树操作。

第一步,对于当前区间[L,R]进行处理。

第二步,枚举所有可能属于当前区间的询问,如果该询问包含本区间,用本区间处理后的答案更新这个询问的答案。

第三步,还原处理数据。

第四步,分治,取mid=L+R>>1,如果某个询问和[L,mid]有交集,那么把这些询问放到询问队列中递归解决左区间。然后再把和[mid+1,R]有交集的询问入队列,递归解决右区间即可。

写了三天,写完我整个人都分治了。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
int n,m,rt[N],tot,nt,num[N],a[N],dy,ans[N],gc,qc,id[N],d[N],dt;
struct qwe
{
int c[2],sum;
}t[N*32];
struct wen
{
int l,r,x,d,s,t;
}q[N];
struct gai
{
int s,v,t;
}g[N],tmpl[N],tmpr[N];
bool cmp(const gai &a,const gai &b)
{
return a.s<b.s;
}
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
int zhao(int x)
{
int l=1,r=nt,re=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(num[mid]<=x)
re=mid,l=mid+1;
else
r=mid-1;
}
return re;
}
void update(int &ro,int pr,int v)
{
ro=++tot;
int x=ro;
for(int i=17;i>=0;i--)
{
t[x].sum=t[pr].sum+1;
t[x].c[0]=t[pr].c[0];
t[x].c[1]=t[pr].c[1];
int d=(v&(1<<i))>>i;
t[x].c[d]=++tot;
x=t[x].c[d];
pr=t[pr].c[d];
}
t[x].sum=t[pr].sum+1;
}
int ques(int l,int r,int v)
{
if(l>r)
return 0;
int re=0;
for(int i=17;i>=0;i--)
{
int d=(v&(1<<i))>>i;
if(t[t[r].c[d^1]].sum-t[t[l].c[d^1]].sum)
{
re+=(1<<i);
l=t[l].c[d^1];
r=t[r].c[d^1];
}
else
{
l=t[l].c[d];
r=t[r].c[d];
}
}
return re;
}
void wk(int ml,int mr)
{
tot=0,nt=0;
for(int i=ml;i<=mr;i++)
{
nt++;
update(rt[nt],rt[nt-1],g[i].v);
num[nt]=g[i].s;
}
for(int i=1;i<=dt;i++)
{
int l=zhao(q[d[i]].l-1),r=zhao(q[d[i]].r);
ans[d[i]]=max(ans[d[i]],ques(rt[l],rt[r],q[d[i]].x));
}
}
void cdq(int gl,int gr,int tl,int tr,int w)
{
if(gl>gr||!w)
return;
int mid=(tl+tr)>>1;
dt=0;
for(int i=1;i<=w;i++)
if(q[id[i]].s<=tl&&q[id[i]].t>=tr)
d[++dt]=id[i];
wk(gl,gr);
int lt=0,rt=0;
for(int i=gl;i<=gr;i++)
{
if(g[i].t<=mid)
tmpl[lt++]=g[i];
else
tmpr[rt++]=g[i];
}
for(int i=0;i<lt;i++)
g[i+gl]=tmpl[i];
for(int i=0;i<rt;i++)
g[i+gl+lt]=tmpr[i];
if(tl==tr)
return;
int idt=0;
for(int i=1;i<=w;i++)
if((q[id[i]].s>tl||q[id[i]].t<tr)&&q[id[i]].s<=mid)
swap(id[i],id[++idt]);
cdq(gl,gl+lt-1,tl,mid,idt);
idt=0;
for(int i=1;i<=w;i++)
if((q[id[i]].s>tl||q[id[i]].t<tr)&&q[id[i]].t>mid)
swap(id[i],id[++idt]);
cdq(gl+lt,gr,mid+1,tr,idt);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
update(rt[i],rt[i-1],a[i]);
}
for(int i=1;i<=m;i++)
{
int o=read();
if(!o)
{
g[++gc].t=++dy;
g[gc].s=read(),g[gc].v=read();
}
else
{
q[++qc].l=read(),q[qc].r=read(),q[qc].x=read();
int d=read();
q[qc].s=max(dy-d,0)+1;
q[qc].t=dy;
ans[qc]=ques(rt[q[qc].l-1],rt[q[qc].r],q[qc].x);
}
}
sort(g+1,g+1+gc,cmp);
for(int i=1;i<=qc;i++)
id[i]=i;
cdq(1,gc,1,dy,qc);
for(int i=1;i<=qc;i++)
printf("%d\n",ans[i]);
return 0;
}

bzoj 4137 [FJOI2015]火星商店问题【CDQ分治+可持久化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]火星商店问题(线段树分治 可持久化Trie)

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

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

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

  4. 【LG4585】[FJOI2015]火星商店问题

    [LG4585][FJOI2015]火星商店问题 题面 bzoj权限题 洛谷 \(Notice:\) 关于题面的几个比较坑的地方: "一天"不是一个操作,而是有0操作就相当于一天开 ...

  5. [FJOI2015]火星商店问题

    [FJOI2015]火星商店问题 神仙线段树分治...不过我不会. 这题用线段树套可持久化Trie还是能写的. 常数有点大,洛谷垫底水平. // luogu-judger-enable-o2 #inc ...

  6. 洛谷 P4585 [FJOI2015]火星商店问题 解题报告

    P4585 [FJOI2015]火星商店问题 题目描述 火星上的一条商业街里按照商店的编号\(1,2,\dots,n\) ,依次排列着\(n\)个商店.商店里出售的琳琅满目的商品中,每种商品都用一个非 ...

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

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

  8. [FJOI2015]火星商店问题(分治+可持久化)

    题目描述 火星上的一条商业街里按照商店的编号1,2 ,…,n ,依次排列着n个商店.商店里出售的琳琅满目的商品中,每种商品都用一个非负整数val来标价.每个商店每天都有可能进一些新商品,其标价可能与已 ...

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

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

随机推荐

  1. Codeforces 659B Qualifying Contest【模拟,读题】

    写这道题题解的目的就是纪念一下半个小时才读懂题...英文一多读一读就溜号... 读题时还时要静下心来... 题目链接: http://codeforces.com/contest/659/proble ...

  2. CodeForces 592C The Big Race

    公倍数之间的情况都是一样的,有循环节. 注意min(a,b)>t的情况和最后一段的处理.C++写可能爆longlong,直接Java搞吧...... import java.io.Buffere ...

  3. <项目><day12>通讯录(视频)

    1 需求分析(需求分析师) 功能分析: 1)添加联系人 2)修改联系人 3)删除联系人 4)查询所有联系人 2 需求设计(系统分析师/架构师/资深开发人员) 2.1设计实体(抽象实体) 联系人实体: ...

  4. Teamviewer ubuntu 提示 TeamViewer Daemon is not running

    http://blog.csdn.net/laohuang1122/article/details/12657343 Ubunut 12.04下面安装了Teamviewer,刚安装完启动是没有问题的, ...

  5. How to Uninstall Internet Explorer 11 for Windows 7

    Internet Explorer 11 is the newest version of Microsoft's web browser, but not everyone is a fan. If ...

  6. poj 1695 Magazine Delivery 记忆化搜索

    dp[a][b][c],表示三个人从小到大依次在a,b.c位置时.距离结束最少的时间. 每次选一个人走到c+1位置搜索就好了. 坑点在于不能floyd.预计题目没说清楚.意思就是假设没送Li,那么Li ...

  7. Registration system

    Registration system 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描写叙述 A new e-mail service "Berlandesk&q ...

  8. 3.2.1 配置构建Angular应用——简单的笔记存储应用——展示功能

    本节我们会通过构建一个简单的笔记存储应用(可以载入并修改一组简单的笔记)来学习如何应用Angular的特性.这个应用用到的特性有: 在JSON文件中存储笔记 展示.创建.修改和删除笔记 在笔记中使用M ...

  9. Linux操作服务器的初识

    1,服务器:顾名思义就是提供服务的机器,(超强性能的一台主机, 100G-500G内存) 2,运维自动化 运维人员, 一个人维护上百台服务器 3,CMDB运维资产管理平台 资产收集, 通过web界面, ...

  10. mongo04---基本查询

    核心: mongod: 数据库核心进程 mongos: 查询路由器,集群时用 mongo: 交互终端(客户端) 二进制导出导入: mongodump:导出bson数据 mongorestore: 导入 ...