bzoj2122: 工作评估

Description

利用空闲时间,BX希望外出工作,工作开始之前,公司就会给BX一个评估值X0,之后每天BX的评估值都是根据上一
天的评估值和当天公司的运行状况得出,即Xi=Xi-1+Di,但是每天的评估值有一个上限,也就是说完整的评估公式
因该是Xi=min{Xi-1+Di,Li}。现在BX已经知道了该公司对自己的初始评估值X0、公司每天的运行状况Di、每天的评
估上限Li,他的空闲时间是从第A天到第B天,他希望找到一段时间i,j (A≤i≤j≤B),使得从第i天开始工作,到
第j天结束后的评估值最大。当然如果任意一段时间的工作得到评估值都<初始评估值X0,BX可以选择不工作,从而
得到最大的评估值。

Input

输入的第一行包含两个整数N、M,分别表示总共工作天数和询问数。
第二行N个数,表示Di。第三行N个数,表示Li。
以下M行,每行3个数A、B、X0,表示一次询问。

Output

M行,每行输出一个整数,表示评估的最大值

Sample Input

6 3
-6 5 3 2 -3 4
8 10 8 1 9 9
1 3 9
2 6 3
3 4 0

Sample Output

10
8
3
【数据规模】
对于100%数据,满足N,M<50001,|Di|<10001,0≤Li<1000000001

分析

分块好题。
首先需要知道两个结论,设 f ( l , r , x 0 ) f(l,r,x_0) f(l,r,x0​)表示以 x 0 x_0 x0​为初始评估值从 l l l走到 r r r的最终评估值。

结论1:若 a ≥ b a\ge b a≥b,则 f ( l , r , a ) ≥ f ( l , r , b ) f(l,r,a) \ge f(l,r,b) f(l,r,a)≥f(l,r,b)
结论2:设 G ( l , r ) = f ( l , r , i n f ) , S ( l , r ) = ∑ i = l r d i G(l,r)=f(l,r,inf),S(l,r)=\sum_{i=l}^{r} d_i G(l,r)=f(l,r,inf),S(l,r)=∑i=lr​di​有 f ( l , r , x 0 ) = min ⁡ { G ( l , r ) , S ( l , r ) + x 0 } f (l,r,x_0)=\min\{G(l,r), S(l,r)+x_0\} f(l,r,x0​)=min{G(l,r),S(l,r)+x0​}

结论1是显然的,对于结论2,如果在某一次被限制 l i l_i li​卡住了,那么答案显然就是 G ( l , r ) G(l,r) G(l,r),否则的话如果一次都没有被卡住,答案就是 S ( l , r ) + x 0 S(l,r)+x_0 S(l,r)+x0​,再由结论1可得, G ( l , r ) ≥ S ( l , r ) + x 0 G(l,r)\ge S(l,r)+x_0 G(l,r)≥S(l,r)+x0​(没有卡住),所以答案直接取 min ⁡ \min min

考虑分块,采用块内快外分开计算贡献的方法。

块内

如果我们已经处理除了任意一对 ( l , r ) (l,r) (l,r)的 G ( l , r ) , S ( l , r ) G(l,r),S(l,r) G(l,r),S(l,r),考虑怎么快速求出答案。
一个显然的事情是,如果 G ( l , r ) ≥ G ( l 1 , r 1 ) ∧ S ( l , r ) ≥ S ( l 1 , r 1 ) G(l,r)\ge G(l_1,r_1)\land S(l,r)\ge S(l_1,r_1) G(l,r)≥G(l1​,r1​)∧S(l,r)≥S(l1​,r1​),那么可以直接舍去 l 1 , r 1 l_1,r_1 l1​,r1​
这样我们得到了一个 G i G_i Gi​递增, S i S_i Si​递减的序列,希望求出 max ⁡ i min ⁡ { G i , S i + x 0 } \max_i\min \{G_i,S_i+x_0\} maxi​min{Gi​,Si​+x0​}
显然可以二分求最大值。

块外

不完整块可以暴力碾过去。
对于一个完整块,有几种选项。

1.从本块开始,从本块结束
2.从本块开始,走到块尾
3.从上一块走过来,从本块结束
4.从上一块走过来,走到块尾
5.不走这一块

于是预处理块内答案,每个位置走到块尾,从块头走到每个位置的 G ( l , r ) , S ( l , r ) G(l,r),S(l,r) G(l,r),S(l,r),用二分的方法求 1 , 2 , 3 1,2,3 1,2,3的答案, 4 4 4直接走过去, 5 5 5用开始的答案更新即可。

代码

#include<bits/stdc++.h>
const int M = 250, N = 5e4 + 5;
int ri() {char c = getchar(); int x = 0, f = 1; for(;c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;for(;c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x * f;
}
struct O {int g, s;O(int _g = 0, int _s = 0) : g(_g), s(_s) {}
}o[N], v[M][N], pr[M][M], sf[M][M];
bool cmp(O a, O b) {return a.g == b.g ? a.s < b.s : a.g < b.g;}
int to, tp, st[N], b[N], l[N], r[N], d[N], li[N], s[N], f[M][M][M];
int S(int l, int r) {return s[r] - s[l - 1];}
int G(int L, int R) {return f[b[L]][L - l[b[L]]][R - l[b[L]]];}
int cn(int a, int b) {return a < b ? a : b;}
int cm(int a, int b) {return a > b ? a : b;}
void Up(int &a, int b) {a < b ? a = b : 0;}
void Cal(O *f) {std::sort(o + 1, o + to + 1, cmp);tp = 0;for(int i = 1;i <= to; ++i) {for(;tp && o[i].s >= o[st[tp]].s;) --tp;st[++tp] = i;}f[0].s = tp; for(int i = 1;i <= tp; ++i) f[i] = o[st[i]];
}
void Pre(int x) {for(int L = l[x]; L <= r[x]; ++L) {int st = 0x3f3f3f3f;for(int R = L; R <= r[x]; ++R)st = cn(st + d[R], li[R]), f[x][L - l[x]][R - l[x]] = st;}to = 0;for(int L = l[x]; L <= r[x]; ++L)for(int R = L; R <= r[x]; ++R)o[++to] = O(G(L, R), S(L, R));Cal(v[x]);to = 0;for(int R = l[x]; R <= r[x]; ++R) o[++to] = O(G(l[x], R), S(l[x], R));Cal(pr[x]);to = 0;for(int L = l[x]; L <= r[x]; ++L)o[++to] = O(G(L, r[x]), S(L, r[x]));Cal(sf[x]);
}
O Move(int L, int R, int cr, int st) {int r = cr;for(int u = L; u <= R; ++u) cr = cn(cm(cr, st) + d[u], li[u]), Up(r, cr);return O(cr, r);
}
int Go(O *f, int st) {int L = 1, R = f[0].s;for(;L + 1 < R; ) { int m = L + R >> 1; f[m].g > f[m].s + st ? R = m : L = m;} int r = cn(f[L].g, f[L].s + st); ++L;if(L <= f[0].s) Up(r, cn(f[L].g, f[L].s + st));return r;
}
int Work(int L, int R, int st) {if(b[L] == b[R]) return Move(L, R, st, st).s;O x = Move(L, r[b[L]], st, st); int cr = cm(x.g, st), A = x.s;for(int u = b[L] + 1; u < b[R]; ++u) {Up(A, Go(pr[u], cr)); //上一块接着走,在这一块停下。 Up(A, Go(v[u], st)); //这一块重新走,在这一块停下。 cr = cn(G(l[u], r[u]), S(l[u], r[u]) + cr); //暴力走过这一块。Up(cr, Go(sf[u], st));//这一块重新走,不停下Up(cr, st); //不走这一块 }return cm(A, Move(l[b[R]], R, cr, st).s);
}
int main() {int n = ri(), m = ri(), B = sqrt(n);for(int i = 1;i <= n; ++i) s[i] = s[i - 1] + (d[i] = ri());for(int i = 1;i <= n; ++i) li[i] = ri();for(int i = 1;i <= n; ++i) {b[i] = (i - 1) / B + 1; r[b[i]] = i;!l[b[i]] ? l[b[i]] = i : 0; }for(int i = 1;i <= b[n]; ++i) Pre(i);for(;m--;) {int L = ri(), R = ri(), st = ri();printf("%d\n", Work(L, R, st));}return 0;
}

bzoj2122: 工作评估 分块 二分相关推荐

  1. Bzoj 3343: 教主的魔法(分块+二分答案)

    3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MB Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息 ...

  2. C - Super Mario(分块+二分)

    C - Super Mario(分块+二分) Mario is world-famous plumber. His "burly" figure and amazing jumpi ...

  3. HDU多校1 - 6756 Finding a MEX(分块+二分+树状数组)

    题目链接:点击查看 题目大意:给出一个 n 个点和 m 条边的无向图,每个点都有一个权值,现在需要执行 q 次操作,每次操作分为两种类型: 1 pos val :将第 pos 个点的权值修改为 val ...

  4. P2801-教主的魔法【分块,二分】

    正题 题目链接:https://www.luogu.com.cn/problem/P2801 题目大意 nnn个数字,要求支持 区间加上一个数字www 询问一个区间内不小于www的数的个数 解题思路 ...

  5. 【bzoj3343】教主的魔法 (分块 + 二分)

    传送门(权限题) 题目分析 题意为:给定一个数列,修改和查询两种操作,修改每次给定一个区间,区间的所有元素都加上一个给定值,查询询问一段区间的数权值大于等于给定值的数有多少个. 首先对原序列分块,然后 ...

  6. 【分块】[LUOGU 旅行规划] 分块+二分+凸包优化

    题目: 题目链接:[LUOGU 旅行规划] 题解: (由于这个,,我竟然还去写了二维凸包的模板题作为练习,,,然而,一点用都没有,,,,) 先解释一下题面的意思:就是一个区间加的操作,再加上一个区间的 ...

  7. P4168 [Violet] 分块 + 二分

    题意 传送门 P4168 [Violet]蒲公英 题解 在线求区间众数问题.考虑分块,假设将整个区间分为 T T T 块,块 i i i 的边界为 [ L [ i ] , R [ i ] ) [L[i ...

  8. bzoj2821 作诗(Poetize)分块+二分

    预处理的d[i][j]为第i块到第j点的答案 块外的暴力 #include<iostream> #include<cstdio> #include<cstring> ...

  9. AtCoder 杂题训练

    前言: 因为要普及了,今年没一等就可以退役去学文化课了,所以暑假把历年noip普及组都刷了一遍,离noip还有50+天,想弄点强化训练什么的. 想了想,就这些天学文化课之余有空就把AtCoder之前那 ...

最新文章

  1. NASA前掌门蛰伏10年 打造非冯·诺伊曼架构芯片
  2. 极大似然估计_干货|一文理解极大似然估计
  3. Spring框架中的设计模式(四)
  4. c语言输出星期几的英语表达,C语言程序设计: 输入年月日 然后输出是星期几...
  5. gitHub----如何利用gitHub 展示 项目作品
  6. express基本原理
  7. using编译指令和using声明比较
  8. 计算机综合布线基本知识,综合布线系统基础知识学习
  9. 高旭东:科普返利网站模式,做到知己知彼放心购物!
  10. 解决Access数据库突然变得很大的方法
  11. date linux 计算日期,科技常识:linux命令详解date使用方法(计算母亲节和父亲节日期脚本示例)...
  12. Golang(二十八)[map-底层数据结构]
  13. RedisTemplate hash操作如何使用string类型
  14. 全国率先!北京发文推进电子劳动合同
  15. python 爬虫实践 (爬取链家成交房源信息和价格)
  16. 26 27 28 副词
  17. 站长天下:buyren网上购物论坛的发展
  18. MySql创建Table的时候将编码设置为utf-8
  19. 计算机应用基础教师授课视频,微课在计算机应用基础教学的应用
  20. SpringMVC学习笔记——HelloWorld

热门文章

  1. gitlab搭建 docker-compose
  2. 浙江×××文网文的时间和办理周期
  3. java 异常 中文_Java中所有的运行时异常,带中文解释
  4. 【R语言】Rmarkdown无法启动png装置 unable to start png() device
  5. ZJNU 2021-07-16 个人排位赛5 部分题解
  6. unity3d android包太大了,unity/unity3d编译成android apk包瘦身方法
  7. 手机通讯录联系人恢复?没有备份的你需要知道
  8. 怎么抓取屏幕截图计算机考试时间,在Windows中自动捕获定义时间间隔的屏幕截图 | MOS86...
  9. 装饰百强第一名金螳螂的信息化办公秘籍
  10. java 创建oracle链接_使用Java创建与oracle db的ssl连接