P4585 [FJOI2015]火星商店问题

题目描述

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

火星人在这条商业街购物时,通常会逛这条商业街某一段路上的所有商店,譬如说商店编号在区间\([L,R]\)中的商店,从中挑选\(1\)件自己最喜欢的商品。每个火星人对商品的喜好标准各不相同。通常每个火星人都有一个自己的喜好密码\(x\)。对每种标价为\(val\)的商品,喜好密码为\(x\)的火星人对这种商品的喜好程度与\(val\)异或\(x\)的值成正比。也就是说,\(val \ xor \ x\)的值越大,他就越喜欢该商品。每个火星人的购物卡在所有商店中只能购买最近\(d\)天内(含当天)进货的商品。另外,每个商店都有一种特殊商品不受进货日期限制,每位火星人在任何时刻都可以选择该特殊商品。每个商店中每种商品都能保证供应,不存在商品缺货的问题。

对于给定的按时间顺序排列的事件,计算每个购物的火星人的在本次购物活动中最喜欢的商品,即输出\(val \ xor \ x\)的最大值。这里所说的按时间顺序排列的事件是指以下\(2\)种事件:

事件\(0\),用三个整数\(0,s,v\),表示编号为s的商店在当日新进一种标价为\(v\)的商品。

事件\(1\),用五个整数\(1,L,R,x,d\),表示一位火星人当日在编号为\(L\)到\(R\)的商店购买\(d\)天内的商品,该火星人的喜好密码为\(x\)。

输入输出格式

输入格式:

第\(1\)行中给出\(2\)个正整数\(n,m\),分别表示商店总数和事件总数。

第\(2\)行中有\(n\)个整数,第\(i\)个整数表示商店i的特殊商品标价。

接下来的\(m\)行,每行表示\(1\)个事件。每天的事件按照先事件\(0\),后事件\(1\)的顺序排列。

输出格式:

将计算出的每个事件\(1\)的\(val \ xor \ x\)的最大值依次输出。

说明

\(n, m \le 100000\)

数据中,价格不大于\(100000\)


看题先写了个线段树套可持久化\(trie\)复习。

然后MLE还莫名WA在几百行了,没找到错误于是开始看线段树分治的正解。

结果我太愚钝了看了好几个小时才想明白...


离线分治的基本思想就是借助各种奇奇怪怪的东西消除掉一个维度或几个维度,使剩下的维度可以更简单的进行维护,线段树分治也是这样。

不同的是,线段树分治常常是把询问按某一维度的信息把询问拆开,并放到线段树的节点上进行操作。

具体来说,在这个题我们把询问按时间拆开放到线段树的节点上,然后遍历线段树的同时划分修改,这时候,我们在考虑某个节点的求解的时候,便不需要考虑在这个节点上的修改关于时间这一维度的顺序了。我们可以简单的对这一个节点的修改按地点建可持久化\(trie\),然后把线段树节点上的询问在\(trie\)上询问一下就可以了。

值得一提的是,这里的修改对询问是独立贡献的,才可以这么做。如果形式是其他的,可能需要其他形式的线段树分治了。


Code:

#include <cstdio>
#include <algorithm>
#include <vector>
const int N=1e5+10;
int max(int x,int y){return x>y?x:y;}
int n,m;
struct chg
{
int tim,p,x;
bool friend operator <(chg n1,chg n2){return n1.p<n2.p;}
}C[N],lC[N],rC[N];
int ccnt,qcnt;
struct qry
{
int id,l,r,L,R,x;
}Q[N];
int siz[N*24],ch[N*24][2],tot,root[N],ans[N];
void Insert(int las,int &now,int x,int dep)
{
siz[now=++tot]=siz[las]+1;
if(dep<0) return;
int bit=x>>dep&1;
ch[now][bit^1]=ch[las][bit^1];
Insert(ch[las][bit],ch[now][bit],x,dep-1);
}
int ask(int las,int now,int x,int dep)
{
if(dep<0) return 0;
if(!siz[now]) return -N;
int bit=x>>dep&1;
if(siz[ch[now][bit^1]]-siz[ch[las][bit^1]])
return ask(ch[las][bit^1],ch[now][bit^1],x,dep-1)+(1<<dep);
else
return ask(ch[las][bit],ch[now][bit],x,dep-1);
}
std::vector <int > q[N<<2];
#define ls id<<1
#define rs id<<1|1
void change(int id,int l,int r,int p)
{
if(Q[p].L>Q[p].R) return;
if(Q[p].L<=l&&Q[p].R>=r) {q[id].push_back(p);return;}
int mid=l+r>>1;
if(Q[p].L<=mid) change(ls,l,mid,p);
if(Q[p].R>mid) change(rs,mid+1,r,p);
}
int s[N],cnt;
void work(int id,int l,int r)
{
cnt=tot=0;
for(int i=l;i<=r;i++)
{
s[++cnt]=C[i].p;
Insert(root[cnt-1],root[cnt],C[i].x,17);
}
for(int i=0;i<q[id].size();i++)
{
int p=q[id][i];
int L=std::upper_bound(s+1,s+1+cnt,Q[p].l-1)-s-1;
int R=std::upper_bound(s+1,s+1+cnt,Q[p].r)-s-1;
ans[p]=max(ans[p],ask(root[L],root[R],Q[p].x,17));
}
}
void seg(int id,int l,int r,int L,int R)//前时间后修改
{
if(L>R) return;
work(id,L,R);
if(l==r) return;
int lp=0,rp=0,mid=l+r>>1;
for(int i=L;i<=R;i++)
{
if(C[i].tim<=mid)
lC[++lp]=C[i];
else
rC[++rp]=C[i];
}
for(int i=L;i<=L+lp-1;i++) C[i]=lC[i+1-L];
for(int i=L+lp;i<=R;i++) C[i]=rC[i+1-L-lp];
seg(ls,l,mid,L,L+lp-1),seg(rs,mid+1,r,L+lp,R);
}
int main()
{
scanf("%d%d",&n,&m);
for(int a,i=1;i<=n;i++) scanf("%d",&a),Insert(root[i-1],root[i],a,17);
for(int op,s,v,l,r,x,d,i=1;i<=m;i++)
{
scanf("%d",&op);
if(op)
{
scanf("%d%d%d%d",&l,&r,&x,&d);++qcnt;
Q[qcnt]={qcnt,l,r,max(1,ccnt-d+1),ccnt,x};
}
else
{
scanf("%d%d",&s,&v);++ccnt;
C[ccnt]={ccnt,s,v};
}
}
for(int i=1;i<=qcnt;i++)
{
ans[i]=ask(root[Q[i].l-1],root[Q[i].r],Q[i].x,17);
change(1,1,ccnt,i);
}
std::sort(C+1,C+1+ccnt);
seg(1,1,ccnt,1,ccnt);
for(int i=1;i<=qcnt;i++) printf("%d\n",ans[i]);
return 0;
}

2018.11.29

洛谷 P4585 [FJOI2015]火星商店问题 解题报告的更多相关文章

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

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

  2. [洛谷P4585] [FJOI2015] 火星商店问题

    Description 火星上的一条商业街里按照商店的编号 \(1\),\(2\) ,-,\(n\) ,依次排列着 \(n\) 个商店.商店里出售的琳琅满目的商品中,每种商品都用一个非负整数 \(va ...

  3. 洛谷 P4585 [FJOI2015]火星商店问题

    (勿看,仅作笔记) bzoj权限题... https://www.luogu.org/problemnew/show/P4585 对于特殊商品,直接可持久化trie处理一下即可 剩下的,想了一段时间c ...

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

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

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

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

  6. 洛谷 P2323 [HNOI2006]公路修建问题 解题报告

    P2323 [HNOI2006]公路修建问题 题目描述 输入输出格式 输入格式: 在实际评测时,将只会有m-1行公路 输出格式: 思路: 二分答案 然后把每条能加的大边都加上,然后加小边 但在洛谷的题 ...

  7. Luogu P4585 [FJOI2015]火星商店问题

    颓文化课作业到很晚写篇博客清醒一下 首先我们仔细阅读并猜测了题意之后,就会想到一个暴力的线段树套可持久化0/1Trie的做法,但是它显然是过不去的 由于最近再做线段树分治的题,我们可以想到用线段树分治 ...

  8. 洛谷 P1852 [国家集训队]跳跳棋 解题报告

    P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...

  9. 洛谷 P3299 [SDOI2013]保护出题人 解题报告

    P3299 [SDOI2013]保护出题人 题目描述 出题人铭铭认为给SDOI2012出题太可怕了,因为总要被骂,于是他又给SDOI2013出题了. 参加SDOI2012的小朋友们释放出大量的僵尸,企 ...

随机推荐

  1. docker制作自己的镜像并上传dockerhub

    1.首先注册自己的dockerhub账号,注册地址:https://hub.docker.com 2.在linux服务器登录自己的账号:docker login --username=qiaoyeye ...

  2. Cesium开发添加entity无法显示

    无代码报错,js查询entity数量发现确实添加进去了.但是在底图上就是不显示. 有可能是跨域产生的问题.打开开发者工具Console栏.查看是不是存在跨域错误. 解决跨域后entity正常加载.

  3. OpenLDAP搭建部署

    安装环境: linu系统:      centos7.2版本 OenLDAP:/openldap-2.4.44 下载地址:ftp://ftp.openldap.org/pub/OpenLDAP/ope ...

  4. 【Shell 开发】Shell 目录

    目录 [第一章]Shell 概述 [第二章]Shell 变量 [第三章]Shell 变量的数值计算 [第四章]Shell 条件测试表达式 [shell 练习1]编写Shell条件句练习 [shell ...

  5. spark-local-运行异常-Could not locate executable null\bin\winutils.exe in the Hadoop binaries

    windows下-local模式-运行spark: 1.下载winutils的windows版本 GitHub上,有人提供了winutils的windows的版本,项目地址是:https://gith ...

  6. Yii2 yii\helpers\ArrayHelper

    yii\helpers\ArrayHelper 是一个数组辅助类,提供额外的数组功能函数 toArray($object, $properties = [], $recursive = true) C ...

  7. app开发相关

    app播放UIWebview 没有声音解决: 设置 allowsInlineMediaPlayback  = YES; mediaPlaybackRequiresUserAction = NO

  8. “Hello World!”团队第六周的第二次会议

    今天是我们团队“Hello World!”团队第六周召开的第二次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.代码 一 ...

  9. 【dp】New Keyboard

    http://codeforces.com/gym/101397 B dp[i][j][k]: i为前一个行动的状态,0-switch.1-type,j为当前状态layout的编号,k 是已键入的字符 ...

  10. js正则表达式匹配斜杠 网址 url等

    项目中有个需求,需要从url中截取ID.需要在前台用js匹配截取,所以就百度一下,发现都没有说清楚,所以这里就总结下. 正则表达式如下: var epId=0; //工厂企业ID var urlInd ...