题解

题目太丧,OJ太没有良心,我永远喜欢LOJ!

(TLE报成RE,垃圾洛谷,我永远喜欢LOJ)

好的,平复一下我debug了一上午崩溃的心态= =,写一写这道题的题解

把所有限制去掉,给出一个值,和一堆数种选一个异或起来求最大值,是一个经典的字典树问题,如果去掉了d的限制,我们类似主席树那样求一个可持久化字典树,利用前缀和就可以快速求得一个区间的字典树了,所以对于所有特殊商品,我们先用这些商品更新一下每一个询问

我们可以用线段树套可持久化trie树,然而空间很难办……

那么我们转为对每个线段树的区间,处理所有覆盖这个区间的询问就好了

对于所有后加的商品,按照商店编号排序

然后我们对于时间进行二分,二分到一个时间区间[L,R]

然后我们拿到这个区间里的商品建出一个trie树,然后找到所有询问里能完整覆盖整个时间区间的询问,更新这个询问的答案

再把询问分到左右区间去分治

代码

#include <bits/stdc++.h>
#define MAXN 100005
//#define ivorysi
#define enter putchar('\n')
#define space putchar(' ')
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N,M;
int a[MAXN];
int ch[MAXN * 40][2],Ncnt,rt[MAXN * 2],siz[MAXN * 40],ans[MAXN * 2],cntq,cnti,D,num[MAXN],MK;
struct qry_node {
int L,R,sl,sr,val,id;
}qry[MAXN],tmp[MAXN];
struct change_node {
int s,t,v;
friend bool operator < (const change_node &a,const change_node &b) {
return a.s < b.s;
}
}item[MAXN],DO[MAXN];
void Insert(const int x,int &y,int v,int d) { y = ++Ncnt;
ch[y][0] = ch[x][0],ch[y][1] = ch[x][1];
siz[y] = siz[x];
++siz[y];
if(d < 0) return;
if(v >> d & 1) Insert(ch[x][1],ch[y][1],v,d - 1);
else Insert(ch[x][0],ch[y][0],v,d - 1);
}
int query(int x,int L,int R) {
L = rt[L];R = rt[R];
int res = 0;
for(int i = 16 ; i >= 0 ; --i) {
if(x >> i & 1) {
if(siz[ch[R][0]] > siz[ch[L][0]]) res |= 1 << i,R = ch[R][0],L = ch[L][0];
else R = ch[R][1],L = ch[L][1];
}
else {
if(siz[ch[R][1]] > siz[ch[L][1]]) res |= 1 << i,R = ch[R][1],L = ch[L][1];
else R = ch[R][0],L = ch[L][0];
}
}
return res;
}
void Init() {
read(N);read(M);
for(int i = 1 ; i <= N ; ++i) read(a[i]);
for(int i = 1 ; i <= N ; ++i) {
Insert(rt[i - 1],rt[i],a[i],16);
}
int op,l,r,x,d;
for(int i = 1 ; i <= M ; ++i) {
read(op);
if(op == 1) {
read(l);read(r);read(x);read(d);
ans[i] = query(x,l - 1,r);
if(D != 0 && d != 0) {
qry[++cntq] = (qry_node){l,r,max(1,D - d + 1),D,x,i};
}
}
else {
++D;
ans[i] = -1;
read(x);read(d);
item[++cnti] = (change_node){x,D,d};
}
}
sort(item + 1,item + cnti + 1);
}
void work(int l,int r) {
Ncnt = 0;
MK = 0;
num[0] = 0;
for(int i = l ; i <= r ; ++i){
++MK;
Insert(rt[MK - 1],rt[MK],item[i].v,16);
num[MK] = item[i].s;
}
}
int find(int x) {
int l = 0,r = MK; while(l < r) {
int mid = (l + r + 1) >> 1;
if(num[mid] <= x) l = mid;
else r = mid - 1;
}
return l;
}
void Solve(int cl,int cr,int tl,int tr,int tot) {
if(!tot || cr < cl) return;
work(cl,cr);
for(int i = 1 ; i <= tot ; ++i) {
if(qry[i].sl <= tl && qry[i].sr >= tr) {
int l = find(qry[i].L - 1);
int r = find(qry[i].R);
ans[qry[i].id] = max(ans[qry[i].id],query(qry[i].val,l,r));
}
} int MID = (tl + tr) >> 1;
if(tl == tr) return;
int p = 0,q = tot;
for(int i = 1 ; i <= tot ; ++i) {
if(qry[i].sl <= tl && qry[i].sr >= tr) tmp[q--] = qry[i];
else if(qry[i].sl <= MID) tmp[++p] = qry[i];
else tmp[q--] = qry[i];
}
for(int i = 1 ; i <= tot ; ++i) qry[i] = tmp[i];
int mk = cl,c;
for(int i = cl ; i <= cr ; ++i) if(item[i].t <= MID) DO[mk++] = item[i];
c = mk - cl;
for(int i = cl ; i <= cr ; ++i) if(item[i].t > MID) DO[mk++] = item[i];
for(int i = cl ; i <= cr ; ++i) item[i] = DO[i];
Solve(cl,cl + c - 1,tl,MID,p);
p = 0,q = tot;
for(int i = 1 ; i <= tot; ++i) {
if(qry[i].sl <= tl && qry[i].sr >= tr) tmp[q--] = qry[i];
else if(qry[i].sr > MID) tmp[++p] = qry[i];
else tmp[q--] = qry[i];
}
for(int i = 1 ; i <= tot ; ++i) qry[i] = tmp[i];
Solve(cl + c,cr,MID + 1,tr,p);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve(1,cnti,1,D,cntq);
for(int i = 1 ; i <= M ; ++i) {
if(ans[i] != -1) out(ans[i]),enter;
}
//out(clock());enter;
return 0;
}

【洛谷】P4585 [FJOI2015]火星商店问题的更多相关文章

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

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

  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$树

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

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

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

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

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

  7. [FJOI2015]火星商店问题

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

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

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

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

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

随机推荐

  1. BNU-2017.7.3排位赛1总结

    比赛链接:https://www.bnuoj.com/v3/contest_show.php?cid=9146#info A题 国际象棋棋盘,黑白相间染色. B题 最大值只取决于每个连通块的大小,一个 ...

  2. 「PLC」PLC基本编程

    PLC中无非就是三大量:开关量(数字量).模拟量.脉冲量.只在搞清楚三者之间的关系,你就能熟练的掌握PLC了. PLC编程算法(一) 1. 开关量也称逻辑量,指仅有两个取值,0或1.ON或OFF.它是 ...

  3. HTML不常用的表单属性-fieldset

    这是代码 这是生成的样子 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...

  4. C++ 的getline问题

    在用c++的getline函数的时候碰到两个问题,总结如下: 1.有时候写程序的时候我们会发现getline(cin,str);这样的语句是不会执行,而是直接跳过的, 一般的解决方法是getline一 ...

  5. 您是哪个等级的CSS开发人员?

    我们在不断的学习,追求进步与提高,到底学到什么程度了,到底是 不是真的了解CSS,是哪个层次了呢.我们来对照一下. 第0级:CSS?那不是一个多人射击游戏吗?  CSS? Isn't that a m ...

  6. 【BZOJ】1066: [SCOI2007]蜥蜴

    [算法]网络流-最大流(dinic) [题解] 构图思路: 因为石柱高度是可以被消耗的,即一根石柱可通过的蜥蜴数量有限,取舍问题中这样表示容量的属性显然可以作为网络流中的边. 于是将一根石柱拆成顶部和 ...

  7. 详细说说如何生成验证码—ASP.NET细枝末节(4)

    前言 今天小编详细的说一下,ASP.NET网站开发过程中生成验证码的全部问题. 本文的目标,是让读者了解,生成验证码涉及的全部基础知识问题. 当然这里说的是比较简单的验证码. 真正符合要求的验证码,涉 ...

  8. 【leetcode 简单】第三十一题 买卖股票的最佳时机

    给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出股票. 示例 ...

  9. 深入理解Spring系列之十:DispatcherServlet请求分发源码分析

    转载 https://mp.weixin.qq.com/s/-kEjAeQFBYIGb0zRpST4UQ DispatcherServlet是SpringMVC的核心分发器,它实现了请求分发,是处理请 ...

  10. 在新版linux上编译老版本的kernel出现kernel/timeconst.h] Error 255

    在使用ubuntu16.4编译Linux-2.6.31内核时出现这样的错误 可以修改timeconst.pl的内容后正常编译. 以下是编译错误提示的内容: Can't use 'defined(@ar ...