牛客多校第九场H Cutting Bamboos(主席树 区间比k小的个数)题解
题意:
标记为\(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小的个数)题解的更多相关文章
- 2019牛客多校第⑨场H Cutting Bamboos(主席树+二分)
		
原题:https://ac.nowcoder.com/acm/contest/889/H 题意: 给你一些竹子,q个询问,问你从第l到第r个竹子,如果你要用y次砍完它,并且每次砍下来的长度是相同的,问 ...
 - Cutting Bamboos(2019年牛客多校第九场H题+二分+主席树)
		
题目链接 传送门 题意 有\(n\)棵竹子,然后有\(q\)次操作,每次操作给你\(l,r,x,y\),表示对\([l,r]\)区间的竹子砍\(y\)次,每次砍伐的长度和相等(自己定砍伐的高度\(le ...
 - 牛客网多校训练第九场H Cutting Bamboos
		
题目链接:https://ac.nowcoder.com/acm/contest/889/H 题意:给出n颗竹子的高度,q次询问,每次询问给出l,r,x,y,每次选取[l,r]中的竹子,砍y次砍掉所有 ...
 - 牛客多校第九场 && 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 ...
 - 2018牛客多校第九场E(动态规划,思维,取模)
		
#include<bits/stdc++.h>using namespace std;const long long mod=1000000007,inv=570000004;long l ...
 - 2019年牛客多校第一场 H题XOR 线性基
		
题目链接 传送门 题意 求\(n\)个数中子集内所有数异或为\(0\)的子集大小之和. 思路 对于子集大小我们不好维护,因此我们可以转换思路变成求每个数的贡献. 首先我们将所有数的线性基的基底\(b\ ...
 - 经典单调栈最大子矩形——牛客多校第二场H
		
题目是求次大子矩形,那么在求最大子矩形的时候维护M1,M2即可 转移M2时比较的过程要注意一下 #include<bits/stdc++.h> using namespace std; # ...
 - 线性基算贡献——19牛客多校第一场H
		
/* 给定数组a[],求有多少集合的异或值为0,将这些集合的大小之和求出来 对于每个数来说,如果除去这个数后数组里做出的线性基和这个数线性相关,那么这个数贡献就是2^(n-1-线性基的大小) 反之这个 ...
 - 牛客多校第九场 E All men are brothers 并查集/组合论
		
题意: 一开始有n人互不认识,每回合有两个人认识,认识具有传递性,也就是相互认识的人组成小团体.现在问你每个回合,挑选四个人,这四个人互不认识,有多少种挑选方法. 题解: 认识不认识用并查集维护即可, ...
 
随机推荐
- Linux学习安装
			
Linux学习安装 服务器指的是网络中能对其他机器提供某些服务的计算机系统,相对普通PC, 服务器指的是高性能计算机,稳定性.安全性要求更高 linux安装学习 1.虚拟机 一台硬件的机器 安装vmw ...
 - C# 正则表达式 -- 复习
			
符号解释: \ 特殊的字符,转义 ^ 匹配输入的字符串的开始位置 $ 匹配输入的字符串的结束位置 * 匹配0次或多次,等价于{0,} + 匹配1次或多次,等价于{1,} ? 匹配0次或1次,等价于{0 ...
 - 解决PHP无法监听9000端口问题/502错误解决办法
			
问题背景 配置nginx+php服务的时候,发现网站能打开html,打开php文件就显示502,一般这个是php没启动啊啥的导致不能正常解析php文件. 原因分析 因为nginx解析php文件是交给f ...
 - mysqldump导出数据库导入数据库
			
使用mysqldump命令导出数据库,格式如下,请按实际要求对参数进行替换: mysqldump -u 用户名 -p 数据库名 > 导出的文件名 比如导出数据库business_db: mysq ...
 - Redis持久化之RDB和AOF
			
Redis是一个键值对数据库服务器,由于Redis是内存数据库,那么有很多内存的特点,例如掉电易失,或者进程退出,服务器中的数据也将消失不见,所以需要一种方法将数据从内存中写到磁盘,这一过程称之为数据 ...
 - Linux、JDK、Netty中的NIO与零拷贝
			
一.先理解内核空间与用户空间 Linux 按照特权等级,把进程的运行空间分为内核空间和用户空间,分别对应着下图中, CPU 特权等级分为4个,Linux 使用 Ring 0 和 Ring 3. 内核空 ...
 - EMA algorithm: https://blog.csdn.net/m0_38106113/article/details/81542863
			
EMA algorithm: https://blog.csdn.net/m0_38106113/article/details/81542863
 - Java面向对象(一)----初次见面
			
面向对象 面向过程:根据业务逻辑从上到下写代码 函数式编程:对一些功能的代码封装到函数中,日后无需重复编写,直接调用函数就可以了 面向对象:将所有的功能进行封装,面对的事封装了功能的实体(对象),即面 ...
 - 调度 GMP
			
小结: 1. 当M从P的本地运行队列获取G时, 如果发现本地队列为空会尝试从其他P盗取一半的G过来,这个机制叫做Work Stealing, 2. Q M一定需要p吗? A 不一定.M正在执行原生代码 ...
 - P6739 [BalticOI 2014 Day1] Three Friends 题解
			
目录 写在前面 Solution 何为字符串哈希(可跳过): Code 写在前面 P6739 [BalticOI 2014 Day1] Three Friends 听说这题可以用比较暴力的做法过,比如 ...