【BZOJ 2138】stone
Problem
Description
话说 \(Nan\) 在海边等人,预计还要等上 \(M\) 分钟。为了打发时间,他玩起了石子。
\(Nan\) 搬来了 \(N\) 堆石子,编号为 \(1\) 到 \(N\),每堆包含 \(A_i\) 颗石子。
每 \(1\) 分钟,\(Nan\) 会在编号在 \([L_i, R_i]\) 之间的石堆中挑出任意 \(K_i\) 颗扔向大海(好疼的玩法),如果 \([L_i, R_i]\) 剩下石子不够 \(K_i\) 颗,则取尽量地多。为了保留扔石子的新鲜感,\(Nan\) 保证任意两个区间 \([L_i, R_i]\) 和 \([L_j, R_j]\) ,不会存在 \(L_i\le L_j \& R_j\le R_i\) 的情况,即任意两段区间不存在包含关系。
可是,如果选择不当,可能无法扔出最多的石子,这时 \(Nan\) 就会不高兴了。所以他希望制定一个计划,他告诉你他 \(m\) 分钟打算扔的区间 \([L_i, R_i]\) 以及 \(K_i\)。
现在他想你告诉他,在满足前 \(i-1\) 分钟都取到你回答的颗数的情况下,第 \(i\) 分钟最多能取多少个石子。
Input Format
第一行正整数 \(N\),表示石子的堆数;
第二行正整数 \(x,y,z,P\),(\(1\le x,y,z\le N, P\le500\))
有等式 \(A_i=[(i-x)^2+(i-y)^2+(i-z)^2]\ mod\ P\);
第三行正整数 \(M\) ,表示有 \(M\) 分钟;
第四行正整数 \(K_1,K_2,x,y,z,P\),(\(x,y,z\le1000,P\le10000\))
有等式 \(K_i=(x*K_{i-1}+y*K_{i-2}+z)mod P\)。
接下来 \(M\) 行,每行两个正整数 \(L_i,R_i\)。
\(N\le40000, M\le N, 1\le L_i\le R_i\le N, A_i\le500\)
Output Format
有 \(M\) 行,第 \(i\) 行表示第 \(i\) 分钟最多能取多少石子。
Sample
Input
5
3 2 4 7
3
2 5 2 6 4 9
2 4
1 2
3 5
Output
2
5
5
Explanation
石子每堆个数分别为 \(0,5,2,5,0\)。
第 \(1\) 分钟,从第 \(2\) 到第 \(4\) 堆中选 \(2\) 个;
第 \(2\) 分钟,从第 \(1\) 到第 \(2\) 堆中选 \(5\) 个;
第 \(3\) 分钟,从第 \(3\) 到第 \(5\) 堆中选 \(8\) 个,但最多只能选 \(5\) 个。
Algorithm
线段树
Mentality
神奇题目。由于它要求的策略不针对整体,只需要局部最优,所以才有了解法。
设当前处理到了第 \(p\) 个区间。
设 \(S_{i,j}\) 为区间 \([i,j]\) 里的石子数之和,设 \(T_{i,j}\) 为之前的,严格为 \([i,j]\) 子区间的询问区间取的石子数之和。
则在任一时刻,对于任意区间 \([l,r]\) 都应该有 \(T_{l,r}\le S_{l,r}\) ,毕竟拿的石子数总不能多于存在的。
设 \(s_i\) 为 \([1,i]\) 的石子数和,\(Tl_i\) 为之前的,左端点位于 \([1,i]\) 的询问区间取的石子数之和,\(Tr_i\) 为之前的,右端点端点位于 \([1,i]\) 的询问区间取的石子数之和。
则可以用它们写成不等式:
Tr_r-Tl_{l-1}\le s_r-s_{l-1}\\
s_{l-1}-Tl_{l-1}\le s_r-Tr_r
\]
设 \(g_i = s_{i - 1} - Tl_{i - 1}, f_i = s_i - Tr_i\) ,则必须有 \(g_l\le f_r\) 。对于一个区间而言,最多能取 \(S_{l,r} - T_{l,r}=f_r-g_l\) 个石子。
考虑对于当前询问 \(p\) 而言,\([L_p,R_p]\) 的决策会影响到所有包含此区间的区间 \(T\) 值。为了满足 \(\forall T_{l,r}\le S_{l,r}\) ,则我们能选择的,最多的石子数应该是 \(Min_{l\in[1,L_p], r\in [R_p, n]} S_{l,r} - T_{l,r}\) ,然后和询问所需石子数 \(K_p\) 取 \(Min\)。
由于 \(S_{l,r} - T_{l,r}\) 可以写成 \(f_r-g_l\) 的形式,所以每个询问的答案就可以写成 \(Min_{i\in[R_p,n]}f_i - Max_{i\in[1,L_p]}g_i\) 。
用线段树维护即可。
Code
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
long long read() {
long long x = 0, w = 1;
char ch = getchar();
while (!isdigit(ch)) w = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit(ch)) {
x = (x << 3) + (x << 1) + ch - '0';
ch = getchar();
}
return x * w;
}
#define ls (o << 1)
#define rs ((o << 1) + 1)
#define mid ((l + r) >> 1)
const int Max_n = 4e4 + 5;
int n, m, x, y, z, mod, Ans;
int s[Max_n];
int f[Max_n << 2], g[Max_n << 2], tagf[Max_n << 2], tagg[Max_n << 2];
int L, R, ans;
int ned[Max_n], ln, rn;
bool fl;
int sqr(int x) { return x * x; }
void pushup(int *f, int o) {
if (!fl)
f[o] = min(f[ls], f[rs]);
else
f[o] = max(f[ls], f[rs]);
}
void pushdown(int *f, int *t, int o) {
t[ls] += t[o], f[ls] += t[o];
t[rs] += t[o], f[rs] += t[o];
t[o] = 0;
}
void build(int *f, int o, int l, int r) {
if (l == r) {
if (!fl)
f[o] = s[l];
else
if (l) f[o] = s[l - 1];
return;
}
build(f, ls, l, mid);
build(f, rs, mid + 1, r);
pushup(f, o);
}
void query(int *f, int *t, int o, int l, int r) {
if (L > R) return;
if (l >= L && r <= R) {
if (!fl)
ans = min(ans, f[o]);
else
ans = max(ans, f[o]);
return;
}
pushdown(f, t, o);
if (mid >= L) query(f, t, ls, l, mid);
if (mid < R) query(f, t, rs, mid + 1, r);
pushup(f, o);
}
void add(int *f, int *t, int o, int l, int r) {
if (L > R) return;
if (l >= L && r <= R) {
f[o] += ans, t[o] += ans;
return;
}
pushdown(f, t, o);
if (mid >= L) add(f, t, ls, l, mid);
if (mid < R) add(f, t, rs, mid + 1, r);
pushup(f, o);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("2138.in", "r", stdin);
freopen("2138.out", "w", stdout);
#endif
n = read(), x = read(), y = read(), z = read(), mod = read();
for (int i = 1; i <= n; i++) {
s[i] = (sqr(x - i) % mod + sqr(y - i) % mod + sqr(z - i) % mod) % mod;
s[i] += s[i - 1];
}
fl = 0, build(f, 1, 0, n);
fl = 1, build(g, 1, 0, n);
m = read();
ned[1] = read(), ned[2] = read();
x = read(), y = read(), z = read(), mod = read();
for (int i = 3; i <= m; i++)
ned[i] = (x * ned[i - 1] % mod + y * ned[i - 2] % mod + z) % mod;
for (int q = 1; q <= m; q++) {
ln = read(), rn = read();
ans = -2e9, fl = 1, L = 1, R = ln;
query(g, tagg, 1, 0, n);
Ans = -ans, ans = 2e9, fl = 0, L = rn, R = n;
query(f, tagf, 1, 0, n);
Ans = min(Ans + ans, ned[q]);
printf("%d\n", Ans);
fl = 1, L = ln + 1, ans = -Ans;
add(g, tagg, 1, 0, n);
fl = 0, L = rn;
add(f, tagf, 1, 0, n);
}
}
【BZOJ 2138】stone的更多相关文章
- 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)
1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...
- Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路
首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
- LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego
[bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...
- 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)
dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...
- 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3940 Solved: 1736 Description ...
- 【BZOJ 2132】圈地计划 && 【7.22Test】计划
两种版本的题面 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土 ...
- -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】
[把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...
- 【BZOJ 1032】 [JSOI2007]祖码Zuma
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1032 [题意] [题解] /* 设f[i][j]表示从第i个珠子开始的j个珠子被消除; ...
随机推荐
- css6——通栏平均分布
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 双显卡安装Ubuntu 18.04和NVIDIA驱动
踩坑笔记: 用软碟通制作UBUNTU18.04 LTS启动盘 长按DEL键进入BIOS,关闭Security Boot,设置USB优先启动 在黑白的grub引导界面(第一行是Try Ubuntu- 第 ...
- CSRF的原理与防御 | 你想不想来一次CSRF攻击?
CSRF是Cross Site Request Forgery的缩写,中文翻译过来是跨站请求伪造.这个漏洞往往能给用户带来巨大的损失,CSRF在等保安全检测中,也是一个非常重要的检测项.但是在我们的网 ...
- 【Python成长之路】从零学GUI -- 制作智能聊天机器人
[写在前面] 鹏哥:最近老惹小燕同学不开心,结果都没人陪我聊天了.哎,好无聊呀! 肥宅男:女朋友什么的最无聊了,还没我的图灵机器人好玩. 鹏哥:图灵?好巧,和我部门同名. [效果如下] [实现过程] ...
- Python小数据保存,有多少中分类?不妨看看他们的类比与推荐方案...
小数据存储 我们在编写代码的时候,经常会涉及到数据存储的情况,如果是爬虫得到的大数据,我们会选择使用数据库,或者excel存储.但如果只是一些小数据,或者说关联性较强且存在存储后复用的数据,我们该如何 ...
- iOS 手势及触摸
转自:http://justsee.iteye.com/blog/1885538 一.响应链 在IOS开发中会遇到各种操作事件,通过程序可以对这些事件做出响应. 首先,当发生事件响应时,必须知道由谁来 ...
- iOS Core Animation 简明系列教程
iOS Core Animation 简明系列教程 看到无数的CA教程,都非常的难懂,各种事务各种图层关系看的人头大.自己就想用通俗的语言翻译给大家听,尽可能准确表达,如果哪里有问题,请您指出我会尽 ...
- git配置文件—— .gitattributes
目录 .gitattributes 文档 1. gitattributes文件以行为单位设置一个路径下所有文件的属性,格式如下: 2. 在gitattributes文件的一行中,一个属性(以text属 ...
- [TimLinux] Python 元类
1. type函数 name = "This is a string" print(type(name)) # <class 'str'> print("*& ...
- Python爬虫之cookie的获取、保存和使用【新手必学】
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:huhanghao Cookie,指某些网站为了辨别用户身份.进行ses ...