题意:

标记为\(1-n\)的竹子,\(q\)个询问,每次给出\(l,r,x,y\)。要求为砍区间\(l,r\)的柱子,要求砍\(y\)次把所有竹子砍完,每次砍的时候选一个高度,把比他高的都砍下来,并且这\(y\)次砍下来长度都相等,问第\(x\)次砍在什么高度。

思路:

显然就是要求选一个高度砍,使得剩下的高度为\((sum[r] - sum[l - 1]) - (sum[r] - sum[l - 1])/y * x\),那么直接建好主席树,然后二分出这个高度。

主席树好啊。

代码:

#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<stack>
#include<ctime>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 2e5 + 5;
const int MAXM = 20000000 + 5;
const int INF = 0x3f3f3f3f;
const ull seed = 131;
const ll MOD = 1e9 + 7;
using namespace std; int root[maxn], tot;
vector<ll> vv;
int getId(int x){
return lower_bound(vv.begin(), vv.end(), x) - vv.begin() + 1;
}
struct node{
int lson, rson;
int num;
ll sum;
}T[maxn * 40];
void update(int l, int r, int &now, int pre, int v, int pos){
T[++tot] = T[pre], T[tot].num += v, T[tot].sum += v * vv[pos - 1], now = tot;
if(l == r) return;
int m = (l + r) >> 1;
if(m >= pos)
update(l, m, T[now].lson, T[pre].lson, v, pos);
else
update(m + 1, r, T[now].rson, T[pre].rson, v, pos);
}
ll query(int l, int r, int now, int pre, double k){
if(l == r){
if(vv[l - 1] < k) return T[now].sum - T[pre].sum;
return 0;
}
int m = (l + r) >> 1;
if(vv[r - 1] < k) return T[now].sum - T[pre].sum;
if(vv[m - 1] < k)
return T[T[now].lson].sum - T[T[pre].lson].sum + query(m + 1, r, T[now].rson, T[pre].rson, k);
else
return query(l, m, T[now].lson, T[pre].lson, k);
} ll querynum(int l, int r, int now, int pre, double k){
if(l == r){
if(vv[l - 1] < k) return T[now].num - T[pre].num;
return 0;
}
int m = (l + r) >> 1;
if(vv[r - 1] < k) return T[now].num - T[pre].num;
if(vv[m - 1] < k)
return T[T[now].lson].num - T[T[pre].lson].num + querynum(m + 1, r, T[now].rson, T[pre].rson, k);
else
return querynum(l, m, T[now].lson, T[pre].lson, k);
} ll h[maxn], psum[maxn];
int main(){
int n, Q;
vv.clear();
tot = 0;
T[0].lson = T[0].rson = T[0].num = T[0].sum = 0; scanf("%d%d", &n, &Q);
psum[0] = 0;
for(int i = 1; i <= n; i++){
scanf("%lld", &h[i]);
vv.push_back(h[i]);
psum[i] = psum[i - 1] + h[i];
}
sort(vv.begin(), vv.end());
vv.erase(unique(vv.begin(), vv.end()), vv.end()); for(int i = 1; i <= n; i++){
update(1, vv.size(), root[i], root[i - 1], 1, getId(h[i]));
} while(Q--){
int l, r, x, y;
scanf("%d%d%d%d", &l, &r, &x, &y);
double per = (psum[r] - psum[l - 1]) * 1.0 / y;
double f = (psum[r] - psum[l - 1]) * 1.0 - per * x;
double L = 0, R = f + 10, m, ans;
while(R - L > 1e-7){
m = (L + R) / 2.0;
double small = query(1, vv.size(), root[r], root[l - 1], m);
int num = querynum(1, vv.size(), root[r], root[l - 1], m);
double now = small + (r - l + 1 - num) * 1.0 * m;
if(now >= f){
ans = m;
R = m;
}
else L = m;
}
printf("%.8f\n", ans);
}
return 0;
}

牛客多校第九场H Cutting Bamboos(主席树 区间比k小的个数)题解的更多相关文章

  1. 2019牛客多校第⑨场H Cutting Bamboos(主席树+二分)

    原题:https://ac.nowcoder.com/acm/contest/889/H 题意: 给你一些竹子,q个询问,问你从第l到第r个竹子,如果你要用y次砍完它,并且每次砍下来的长度是相同的,问 ...

  2. Cutting Bamboos(2019年牛客多校第九场H题+二分+主席树)

    题目链接 传送门 题意 有\(n\)棵竹子,然后有\(q\)次操作,每次操作给你\(l,r,x,y\),表示对\([l,r]\)区间的竹子砍\(y\)次,每次砍伐的长度和相等(自己定砍伐的高度\(le ...

  3. 牛客网多校训练第九场H Cutting Bamboos

    题目链接:https://ac.nowcoder.com/acm/contest/889/H 题意:给出n颗竹子的高度,q次询问,每次询问给出l,r,x,y,每次选取[l,r]中的竹子,砍y次砍掉所有 ...

  4. 牛客多校第九场 && ZOJ3774 The power of Fibonacci(二次剩余定理+斐波那契数列通项/循环节)题解

    题意1.1: 求\(\sum_{i=1}^n Fib^m\mod 1e9+9\),\(n\in[1, 1e9], m\in[1, 1e4]\) 思路1.1 我们首先需要知道斐波那契数列的通项是:\(F ...

  5. 2018牛客多校第九场E(动态规划,思维,取模)

    #include<bits/stdc++.h>using namespace std;const long long mod=1000000007,inv=570000004;long l ...

  6. 2019年牛客多校第一场 H题XOR 线性基

    题目链接 传送门 题意 求\(n\)个数中子集内所有数异或为\(0\)的子集大小之和. 思路 对于子集大小我们不好维护,因此我们可以转换思路变成求每个数的贡献. 首先我们将所有数的线性基的基底\(b\ ...

  7. 经典单调栈最大子矩形——牛客多校第二场H

    题目是求次大子矩形,那么在求最大子矩形的时候维护M1,M2即可 转移M2时比较的过程要注意一下 #include<bits/stdc++.h> using namespace std; # ...

  8. 线性基算贡献——19牛客多校第一场H

    /* 给定数组a[],求有多少集合的异或值为0,将这些集合的大小之和求出来 对于每个数来说,如果除去这个数后数组里做出的线性基和这个数线性相关,那么这个数贡献就是2^(n-1-线性基的大小) 反之这个 ...

  9. 牛客多校第九场 E All men are brothers 并查集/组合论

    题意: 一开始有n人互不认识,每回合有两个人认识,认识具有传递性,也就是相互认识的人组成小团体.现在问你每个回合,挑选四个人,这四个人互不认识,有多少种挑选方法. 题解: 认识不认识用并查集维护即可, ...

随机推荐

  1. Linux学习安装

    Linux学习安装 服务器指的是网络中能对其他机器提供某些服务的计算机系统,相对普通PC, 服务器指的是高性能计算机,稳定性.安全性要求更高 linux安装学习 1.虚拟机 一台硬件的机器 安装vmw ...

  2. C# 正则表达式 -- 复习

    符号解释: \ 特殊的字符,转义 ^ 匹配输入的字符串的开始位置 $ 匹配输入的字符串的结束位置 * 匹配0次或多次,等价于{0,} + 匹配1次或多次,等价于{1,} ? 匹配0次或1次,等价于{0 ...

  3. 解决PHP无法监听9000端口问题/502错误解决办法

    问题背景 配置nginx+php服务的时候,发现网站能打开html,打开php文件就显示502,一般这个是php没启动啊啥的导致不能正常解析php文件. 原因分析 因为nginx解析php文件是交给f ...

  4. mysqldump导出数据库导入数据库

    使用mysqldump命令导出数据库,格式如下,请按实际要求对参数进行替换: mysqldump -u 用户名 -p 数据库名 > 导出的文件名 比如导出数据库business_db: mysq ...

  5. Redis持久化之RDB和AOF

    Redis是一个键值对数据库服务器,由于Redis是内存数据库,那么有很多内存的特点,例如掉电易失,或者进程退出,服务器中的数据也将消失不见,所以需要一种方法将数据从内存中写到磁盘,这一过程称之为数据 ...

  6. Linux、JDK、Netty中的NIO与零拷贝

    一.先理解内核空间与用户空间 Linux 按照特权等级,把进程的运行空间分为内核空间和用户空间,分别对应着下图中, CPU 特权等级分为4个,Linux 使用 Ring 0 和 Ring 3. 内核空 ...

  7. EMA algorithm: https://blog.csdn.net/m0_38106113/article/details/81542863

    EMA algorithm: https://blog.csdn.net/m0_38106113/article/details/81542863

  8. Java面向对象(一)----初次见面

    面向对象 面向过程:根据业务逻辑从上到下写代码 函数式编程:对一些功能的代码封装到函数中,日后无需重复编写,直接调用函数就可以了 面向对象:将所有的功能进行封装,面对的事封装了功能的实体(对象),即面 ...

  9. 调度 GMP

    小结: 1. 当M从P的本地运行队列获取G时, 如果发现本地队列为空会尝试从其他P盗取一半的G过来,这个机制叫做Work Stealing, 2. Q M一定需要p吗? A 不一定.M正在执行原生代码 ...

  10. P6739 [BalticOI 2014 Day1] Three Friends 题解

    目录 写在前面 Solution 何为字符串哈希(可跳过): Code 写在前面 P6739 [BalticOI 2014 Day1] Three Friends 听说这题可以用比较暴力的做法过,比如 ...