牛客练习赛14 B 区间的连续段 (倍增)
链接:https://ac.nowcoder.com/acm/contest/82/B
来源:牛客网
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
给你一个长为n的序列a和一个常数k
有m次询问,每次查询一个区间[l,r]内所有数最少分成多少个连续段,使得每段的和都 <= k
如果这一次查询无解,输出"Chtholly"
输入描述:
- 第一行三个数n,m,k
第二行n个数表示这个序列a
之后m行,每行给出两个数l r表示一次询问
输出描述:
- 输出m行,每行一个整数,表示答案
备注:
对于100%的数据,1 <= n , m <= 1000000 , 1 <= ai , k <= 1000000000
题意:
给你一个数组,和一个整数k,和q次询问,每一次询问给你一个l,r
问你最少把数组分成多少个连续部分,使每一个连续的sum和小于等于k。
思路:
2进制倍思想,
因为n<=1e6 所以我们倍增数组只需要开到 20 ,因为 1<<20 是1048576 >1e6
我们开倍增数组 st[i][j] 表示 第i个 数右移1<<j 到的最远的距离,
那么我们维护好这个信息后,对于每一个询问,我们只需要贪心的求解即可。
lg[i] 代表 log2(i) 可以证明 从 l到r,我们可以在 log2(r-l+1) ,log2(r-l),log2(r-l-1)...log2(1) 选择一些数加上到达。
那么我们只需要贪心的 让当前的pos 右移 log2(r-l+1) 远是否小于等于R,如果小于等于就移动,然后再更细(小)一步的移动。即可,最后判断是否移动到了R来决定输出什么即可。
细节见代码:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <cmath>
- #include <queue>
- #include <stack>
- #include <map>
- #include <set>
- #include <vector>
- #include <iomanip>
- #define ALL(x) (x).begin(), (x).end()
- #define rt return
- #define dll(x) scanf("%I64d",&x)
- #define xll(x) printf("%I64d\n",x)
- #define sz(a) int(a.size())
- #define all(a) a.begin(), a.end()
- #define rep(i,x,n) for(int i=x;i<n;i++)
- #define repd(i,x,n) for(int i=x;i<=n;i++)
- #define pii pair<int,int>
- #define pll pair<long long ,long long>
- #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
- #define MS0(X) memset((X), 0, sizeof((X)))
- #define MSC0(X) memset((X), '\0', sizeof((X)))
- #define pb push_back
- #define mp make_pair
- #define fi first
- #define se second
- #define eps 1e-6
- #define gg(x) getInt(&x)
- #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
- using namespace std;
- typedef long long ll;
- ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
- ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
- ll powmod(ll a, ll b, ll MOD) {ll ans = ; while (b) {if (b % )ans = ans * a % MOD; a = a * a % MOD; b /= ;} return ans;}
- inline void getInt(int* p);
- const int maxn = ;
- const int inf = 0x3f3f3f3f;
- /*** TEMPLATE CODE * * STARTS HERE ***/
- ll n, m, k;
- ll a[maxn];
- ll lg[maxn];
- int st[maxn][];
- int main()
- {
- //freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);
- //freopen("D:\\common_text\\code_stream\\out.txt","w",stdout);
- gbtb;
- cout << ( << ) << endl;
- cin >> n >> m >> k;
- repd(i, , n)
- {
- cin >> a[i];
- }
- repd(i, , n)
- {
- lg[i] = lg[i / ] + ;
- }
- repd(i, , n)
- {
- a[i] += a[i - ];
- }
- int pos;
- repd(i, , )
- {
- st[n + ][i] = n + ;
- }
- for (int i = n; i >= ; i--)
- {
- pos = upper_bound(a + , a + + n, a[i - ] + k) - a;
- st[i][] = pos;
- repd(j, , )
- {
- st[i][j] = st[st[i][j - ]][j - ];
- }
- }
- int l, r;
- repd(t, , m)
- {
- cin >> l >> r;
- pos = l;
- int ans = ;
- for (int j = lg[r - l + ]; j >= ; j--)
- {
- if (st[pos][j] <= r)
- {
- pos = st[pos][j];
- ans += ( << j);
- }
- }
- if (st[pos][] <= r)
- {
- cout << "Chtholly" << endl;
- } else
- {
- cout << ans + << endl;
- }
- }
- return ;
- }
- inline void getInt(int* p) {
- char ch;
- do {
- ch = getchar();
- } while (ch == ' ' || ch == '\n');
- if (ch == '-') {
- *p = -(getchar() - '');
- while ((ch = getchar()) >= '' && ch <= '') {
- *p = *p * - ch + '';
- }
- }
- else {
- *p = ch - '';
- while ((ch = getchar()) >= '' && ch <= '') {
- *p = *p * + ch - '';
- }
- }
- }
牛客练习赛14 B 区间的连续段 (倍增)的更多相关文章
- 牛客练习赛14 D 比较月亮大小 【水】
链接:https://www.nowcoder.com/acm/contest/82/D 来源:牛客网 比较月亮大小 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其 ...
- 牛客练习赛14 D比较月亮大小 (实现)
链接:https://ac.nowcoder.com/acm/contest/82/D来源:牛客网 题目描述 点点是一名出色的狼人.众所周知,狼人只有在满月之夜才会变成狼. 同时,月亮的大小随着时间变 ...
- 牛客练习赛14 E - 无向图中的最短距离 (bfs+bitset)
一个链接:https://ac.nowcoder.com/acm/contest/82/E来源:牛客网 无向图中的最短距离 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144 ...
- 牛客练习赛14 A n的约数 (数论)
链接:https://ac.nowcoder.com/acm/contest/82/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288 ...
- 牛客练习赛28-B(线段树,区间更新)
牛客练习赛28 - B 传送门 题目 qn姐姐最好了~ qn姐姐给你了一个长度为n的序列还有m次操作让你玩, 1 l r 询问区间[l,r]内的元素和 2 l r 询问区间[l,r]内的 ...
- 牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 逻辑,博弈 B
牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 https://ac.nowcoder.com/acm/contest/218/B 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2621 ...
- 牛客练习赛 29 E 位运算?位运算!(线段树)
题目链接 牛客练习赛29E 对$20$位分别建立线段树.首先$1$和$2$可以合起来搞(左移右移其实是等效的) 用个lazy标记下.转移的时候加个中间变量. $3$和$4$其实就是区间$01$覆盖操 ...
- 牛客练习赛53 A 超越学姐爱字符串 (DP)
牛客练习赛53 超越学姐爱字符串 链接:https://ac.nowcoder.com/acm/contest/1114/A来源:牛客网 超越学姐非常喜欢自己的名字,以至于英文字母她只喜欢" ...
- 【并查集缩点+tarjan无向图求桥】Where are you @牛客练习赛32 D
目录 [并查集缩点+tarjan无向图求桥]Where are you @牛客练习赛32 D PROBLEM SOLUTION CODE [并查集缩点+tarjan无向图求桥]Where are yo ...
随机推荐
- ide破解
https://blog.csdn.net/yangying496875002/article/details/73603303
- 在windows下使用Mingw搭建模拟Linux
1.到官网下载最新版Mingw 2.点击安装,最好选择默认路径,如果不是的话,路径中一定不能有空格. 3.选择安装,mingw-developer-toolkit.mingw32-base.mingw ...
- mysql 批量删表
Select CONCAT( 'drop table ', table_name, ';' ) FROM information_schema.tables Where table_name LIKE ...
- 2018.03.27 python pandas merge join 使用
#2.16 合并 merge-join import numpy as np import pandas as pd df1 = pd.DataFrame({'key1':['k0','k1','k2 ...
- Linux下安装Elasticsearch6.5
1.安装JDK8(Elastic 需要 Java 8 环境) 1)下载jdk8文件:http://www.oracle.com/technetwork/java/javase/downloads/jd ...
- Scratch少儿编程系列:(二)界面介绍及相关概念
本系列后续所有Scratch的讲解均基于2.0版本介绍.系统启动后,界面如下: Scratch主要包括6个区域: 1. 菜单:新建.打开.保存 Scratch文件,2.0版本文件后缀名为 .sb2 2 ...
- IP子网的划分
一.划分子网的具体步骤 已知192.168.1.0/24,划分8个子网(一个ip划分8个子网,即网络位不再是24位)1100 0000.1010 1000.0000 0001.0000 00001 . ...
- .net core 学习小结之 PostMan报415
首先415的官方解释是:对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝. 也就是说我所准备的数据格式并不是后台代码使用的数据格式 后台代码如下 using ...
- C#获取当前路径7中方法
//获取模块的完整路径. string path1 = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; //获取 ...
- [转帖]22款让Kubernetes锦上添花的开源工具
22款让Kubernetes锦上添花的开源工具 http://soft.zhiding.cn/software_zone/2019/0506/3117650.shtml 找时间尝试一下. 至顶网软件频 ...