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. selenium自动化之处理浏览器警告弹窗

    有的网站会弹出类似如下图的警告弹窗,你会发现这种弹窗在html源码中怎么也定位不到,接下来将介绍这种弹窗的处理方式. 其实这种弹窗是不属于html的元素的,他是属于浏览器自带的弹窗,所以用定位元素的方 ...

  2. cookie,session傻傻分不清楚?

    做了这么多年测试,还是分不清什么是cookie,什么是session?很正常,很多初级开发工程师可能到现在都搞不清什么是session,cookie相对来说会简单很多. 下面这篇文章希望能够帮助大家分 ...

  3. 测试Websocket建立通信,使用protobuf格式交换数据

    接到一个应用测试,应用实现主要使用websocket保持长链接,使用protobuf格式交换数据,用途为发送消息,需要我们测试评估性能,初步评估需要测试长链接数.峰值消息数以及长期运行稳定性 整体需求 ...

  4. Unity Lighting - Light Probes 光照探针(十)

      Light Probes 光照探针 Only static objects are considered by Unity’s Baked or Precomputed Realtime GI s ...

  5. 【转载】IntelliJ IDEA 2017常用快捷键

    IntelliJ IDEA 是一款致力于提供给开发工程师沉浸式编程体验的IDE工具,所以在其中提供了很多方便高效的快捷键,一旦熟练掌握,整个开发的效率和体验将大大提升.本文就按照笔者自己日常开发时的使 ...

  6. Linux内核学习笔记(5)-- 进程调度概述

    进程调度程序是多任务操作系统的基础,它是确保进程能有效工作的一个内核子系统,负责决定哪个进程投入运行.何时运行以及运行多长时间.只有通过进程调度程序的合理调度,系统资源才能够最大限度地发挥作用,多进程 ...

  7. TCP半开连接与半闭连接

    半打开(Half-Open)连接和半关闭(Half-Close)连接.TCP是一个全双工(Full-Duplex)协议,因此这里的半连接"半"字就是相对于全双工的"全&q ...

  8. loadrunner socket协议问题归纳(6)

    首先让我们先看一下loadrunner- winsock 函数 一览表: lrs_accept_connection 接受侦听套接字连接 lrs_close_socket 关闭打开的套接字       ...

  9. 关于requestanimationframe

    首先字面理解,请求动画框架, 用法: var nextFrame = (function() { return window.requestAnimationFrame || window.webki ...

  10. ORM(object relational Maping)

    ORM即对象关系映射,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中.本质上 ...