牛客多校第九场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人互不认识,每回合有两个人认识,认识具有传递性,也就是相互认识的人组成小团体.现在问你每个回合,挑选四个人,这四个人互不认识,有多少种挑选方法. 题解: 认识不认识用并查集维护即可, ...
随机推荐
- [Poi2012]Rendezvous
题目描述 给定一个n个顶点的有向图,每个顶点有且仅有一条出边. 对于顶点i,记它的出边为(i, a[i]). 再给出q组询问,每组询问由两个顶点a.b组成,要求输出满足下面条件的x.y: 从顶点a沿着 ...
- .NET Core使用Source Link提高源代码调试体验和生产效率
前言: 在我们日常开发过程中常常会使用到很多其他封装好的第三方中间件(NuGet依赖项).类库或者是.NET框架中自带的库.但是当你想要对这些类库的方法设置断点调试,然后发现无法F11(逐语句)调试进 ...
- 前端面试之CSS常用的选择器!
前端面试之CSS常用的选择器! 标签选择器 <style> /* <!-- 标签选择器 :写上标签名 -->*/ p { color: green; } div { color ...
- e.next = nil // avoid memory leaks e.prev = nil // avoid memory leaks
/Go/src/container/list/list.go:10
- TCP报文段的首部格式 20字节的固定首部
<---- IP首部 TCP首部 TCP报文段的数据部分 <---- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...
- HTML Standard系列:Event loop、requestIdleCallback 和 requestAnimationFrame
HTML Standard系列:Event loop.requestIdleCallback 和 requestAnimationFrame - 掘金 https://juejin.im/post/5 ...
- Spring常见问题总结
1. 什么是 Spring 框架? Spring 是一种轻量级开发框架,旨在提高开发人员的开发效率以及系统的可维护性.Spring 官网:https://spring.io/. 我们一般说 Sprin ...
- Hash Map集合和Hash Set集合
HashMap集合的使用 1.1.每个集合对象的创建(new) 1.2.从集合中添加元素 1.3.从集合中取出某个元素 1.4.遍历集合 public class HashMapTest { publ ...
- P6739 [BalticOI 2014 Day1] Three Friends 题解
目录 写在前面 Solution 何为字符串哈希(可跳过): Code 写在前面 P6739 [BalticOI 2014 Day1] Three Friends 听说这题可以用比较暴力的做法过,比如 ...
- 【算法】数位 dp
时隔多日,我终于再次开始写博客了!! 上午听了数位 dp,感觉没听懂,于是在网上进行一番愉 ♂ 快 ♀ 的学习后,写篇博来加深一下印象~~ 前置的没用的知识 数位 不同计数单位,按照一定顺序排列,它们 ...