牛客练习赛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 ...
随机推荐
- Mybatis 一对多 关联查询查询
一对多 与 一对一 查询有许多相似之处. 最主要的区别是 查询结果是list,与之对应的标签为collection. 班级和学生,一个班有多个学生,而每个学生只能属于一个班. 此时班级编号作为学生表的 ...
- 启动webpack-dev-server错误,ERROR in main.js from UglifyJs Unexpected token: name «element», expected: punc «;»
启动webpack-dev-server出现以下错误 ERROR in main.js from UglifyJsUnexpected token: name «element», expected: ...
- 使用discriminator实现鉴别器
1在人员接口实现方法 public Employee getEmpByIdStep(Integer id); 2在映射文件进行配置 <!-- public Employee getEmpById ...
- Git-Runoob:Git 安装配置
ylbtech-Git-Runoob:Git 安装配置 1.返回顶部 1. Git 安装配置 在使用Git前我们需要先安装 Git.Git 目前支持 Linux/Unix.Solaris.Mac和 W ...
- java利用zip解压slpk文件
public static void main(String[] args) { File file = new File("C:\\Users\\Administrator\\Deskto ...
- 创建Stream
1.创建Stream create Stream from Collections; create Stream from values; create Stream from Arrays; cra ...
- python学习笔记:(三)list(列表)常用的内置方法
list(列表)包含一些内置的方法,以下为详细介绍: (方法调用:对象.方法(参数)) 1.append() 在列表的末尾添加新的对象 如: lst=[1,2,3] lst.append(4) --- ...
- Python学习之==>线程&&进程
一.什么是线程(thread) 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一个线程指的是进程中一个单一顺序的控制流,一个进程中可以包含多个线程,每条线程并行 ...
- 基于Python对象引用、可变性和垃圾回收详解
基于Python对象引用.可变性和垃圾回收详解 下面小编就为大家带来一篇基于Python对象引用.可变性和垃圾回收详解.小编觉得挺不错的,现在就分享给大家,也给大家做个参考. 变量不是盒子 在示例所示 ...
- 学用 TStringGrid [6] - Options
本例运行效果图: 一般修改 TStringGrid 的 Options 直接在设计时选一下 True 或 False 就行了; 代码中可以像下面操作: StringGrid1.Options := ...