牛客网多校训练第九场H Cutting Bamboos
题目链接:https://ac.nowcoder.com/acm/contest/889/H
题意:给出n颗竹子的高度,q次询问,每次询问给出l,r,x,y,每次选取[l,r]中的竹子,砍y次砍掉所有竹子,每次砍下来的竹子长度和是相同的,问你第x次应该砍在哪个高度上
解题思路:由于总共砍的次数已经给出,因此我们可以知道砍x次总共砍的量 Total = $\sum\limits_{i=l}^{r}$h[i]*x/y,那么问题就变成了一个方程$\sum\limits_{i=l}^{r}$,我们需要求的就是ansmax(0,h[i]-ans)=Total
也就是求出区间内大于ans的数减掉ans的和等于Total,利用主席树我们可以求出区间大于一个数的个数num和它们的和sum,接下来我们只需二分ans验证即可。时间复杂度O($nlog^{2}n$),后来我了解到一种更好的做法,
我们需要取区间大于ans的一段数去计算答案,因此我们递归处理这个区间[L,R],先计算以右区间[M+1,R]的值代入方程,然后以区间中值M(为什么选M,后面会解释)作为假设的ans,这时我们可以得到一个值tmp,令val=Total
1、如果tmp<Total,说明这个ans选的太大了,我们还需要一个更小的ans,因此递归处理当前区间的[L,M]去找寻更适合的ans,这时递归我们需要让val-=tmp,也就是说,我们只需要传入当前的偏差值进去,在递归到左区间[L,M]时,我们继续选取区间中值ML作为假设的ans,这时我们需要重新计算tmp值,然而当前的Total已经出现了问题(它是根据上一次的假设ans=M计算的),为了修正Total,我们只需在计算tmp时加上前一次减掉的num个M(也就是当前左区间的R,这也是为什么选取M作为假设ans的原因了,我们可以得到上一次的假设ans),然后对当前的假设ans=ML重新计算tmp值,注意,我们要维护一个当前已经选取的竹子数量num,这样我们才可以去计算tmp,计算好tmp值后,继续递归即可
2、如果tmp>Total,说明这个ans选的太小了,我们需要到右区间[M+1,R]去重新寻找合适的假设ans,因此我们保持参数不变递归右区间即可
当我们到达递归终点,L==R时,说明,我们如果选择R为假设值仍然存在偏差val(val可能是0,但这没关系),而选择L-1会导致$\sum\limits_{i=l}^{r}$,max(0,h[i]-ans)>Total
因此我们可以根据这个偏差值val去修正假设的ans=L去得到真正的答案,真正的ans=L-val/(以及选取的所有竹子个数+高为L的竹子个数(以L为假设ans时,我们认为高为L的竹子是没有被砍的))时间复杂度O(nlogn)
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+;
#define eps 1e-8
struct Node
{
int l,r,num;
ll sum;
}node[maxn*];
int h[maxn],root[maxn],tot;
ll preSum[maxn];
void update(int &x,int y,int l,int r,int val)
{
x=++tot;
node[x]=node[y];
++node[x].num;
node[x].sum+=val;
if(l==r)return;
int m=(l+r)>>;
if(val<=m)update(node[x].l,node[y].l,l,m,val);
else update(node[x].r,node[y].r,m+,r,val);
}
double query(int x,int y,int L,int R,double val,ll num)
{
if(L==R)return L-val/(node[x].num-node[y].num+num);
int m=(L+R)>>;
ll cnt=node[node[x].r].num-node[node[y].r].num;
ll tmp=node[node[x].r].sum-node[node[y].r].sum-cnt*m+num*(R-m);
if(tmp+eps<val)return query(node[x].l,node[y].l,L,m,val-tmp,num+cnt);
return query(node[x].r,node[y].r,m+,R,val,num);
}
int main() {
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
int n, q;
cin >> n >> q;
for (int i = ; i <= n; i++) {
cin >> h[i];
preSum[i] = preSum[i - ] + h[i];
update(root[i], root[i - ], , 1e5, h[i]);
}
while (q--) {
int l, r, x, y;
cin >> l >> r >> x >> y;
printf("%.12f\n", query(root[r], root[l - ], , 1e5, 1.0 * (preSum[r] - preSum[l - ]) / y * x, ));
}
return ;
}
牛客网多校训练第九场H Cutting Bamboos的更多相关文章
- 牛客网多校赛第九场A-circulant matrix【数论】
链接:https://www.nowcoder.com/acm/contest/147/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...
- 牛客网多校训练第二场D Kth Minimum Clique
链接:https://ac.nowcoder.com/acm/contest/882/D来源:牛客网 Given a vertex-weighted graph with N vertices, fi ...
- 牛客网多校训练第一场 J - Different Integers(树状数组 + 问题转换)
链接: https://www.nowcoder.com/acm/contest/139/J 题意: 给出n个整数的序列a(1≤ai≤n)和q个询问(1≤n,q≤1e5),每个询问包含两个整数L和R( ...
- 牛客网多校训练第一场 I - Substring(后缀数组 + 重复处理)
链接: https://www.nowcoder.com/acm/contest/139/I 题意: 给出一个n(1≤n≤5e4)个字符的字符串s(si ∈ {a,b,c}),求最多可以从n*(n+1 ...
- 牛客网多校训练第一场 F - Sum of Maximum(容斥原理 + 拉格朗日插值法)
链接: https://www.nowcoder.com/acm/contest/139/F 题意: 分析: 转载自:http://tokitsukaze.live/2018/07/19/2018ni ...
- 牛客网多校训练第一场 E - Removal(线性DP + 重复处理)
链接: https://www.nowcoder.com/acm/contest/139/E 题意: 给出一个n(1≤n≤1e5)个整数(范围是1至10)的序列,求从中移除m(1≤m≤min(n-1, ...
- 牛客网多校训练第一场 D - Two Graphs
链接: https://www.nowcoder.com/acm/contest/139/D 题意: 两个无向简单图都有n(1≤n≤8)个顶点,图G1有m1条边,图G2有m2条边,问G2有多少个子图与 ...
- 牛客网多校训练第一场 B - Symmetric Matrix(dp)
链接: https://www.nowcoder.com/acm/contest/139/B 题意: 求满足以下条件的n*n矩阵A的数量模m:A(i,j) ∈ {0,1,2}, 1≤i,j≤n.A(i ...
- 牛客网多校训练第一场 A - Monotonic Matrix(Lindström–Gessel–Viennot lemma)
链接: https://www.nowcoder.com/acm/contest/139/A 题意: 求满足以下条件的n*m矩阵A的数量模(1e9+7):A(i,j) ∈ {0,1,2}, 1≤i≤n ...
随机推荐
- dcoker镜像的分层
镜像分层的好处:复用节省磁盘空间,相同的内容只需加载一份到内存 修改dockerfile之后,再次构建速度加快 docker优化: 1.尽可能地选择体积小的linux发行版,比如alpine 2.尽可 ...
- Oracle日志查看
一.Oracle日志的路径: 登录:sqlplus "/as sysdba" 查看路径:SQL> select * from v$logfile; SQL> selec ...
- TurtleBOT3
ubuntu更换源 sudo cp /etc/apt/sources.list /etc/apt/sources_backup.list sudo gedit /etc/apt/sources.lis ...
- Python第十二节 异常
Python 第十三节 异常 python的错误一般包含两类: 语法错误 : 语法错误一般就是, 当你写完程序提交的时候, 发现无法提交, 提示存在错误.例如: 英文逗号 错写成了 中文逗号 异常 : ...
- css雪碧图(精灵图)与字体图标的介绍以及对比
css雪碧图(精灵图)与字体图标的介绍以及对比 设想一个实际场景:在一个页面为了展示,我们放置了很多独立的小图片,浏览器在显示页面的时候,就需要向服务器就会发送很多请求,来获取并加载这些小图片,但是这 ...
- Shell内置命令——declare
- 升级ssh后续问题
升级了openssh后远端的服务器无法通过sftp传输文件到高服务器,后来发现是远端的服务器ssh版本太低,而新升级了openssh的服务器已经不再支持老版本ssh client的相关协议,这时候有两 ...
- Git分布式版本控制系统(上)
Git分布式版本控制系统(上) 链接:https://pan.baidu.com/s/1CgaEv12cwfbs5RxcNpxdAg 提取码:fytm 复制这段内容后打开百度网盘手机App,操作更方便 ...
- C++中创建对象的时候加括号和不加括号的区别(转)
c++创建对象的语法有----- 1 在栈上创建 MyClass a; 2 在堆上创建加括号 MyClass *a= new MyClass(); 3 不加括号 MyClass *a = new My ...
- js中数据操作的某些思想
1,默认数据的复用 写成function的return形式缓存在变量中,用的时候直接执行fun就行了 例如 有文件text.js里面的对象是export default ()=>({aa:55, ...