题目描述

给你一个长为n的序列a和一个常数k

有m次询问,每次查询一个区间[l,r]内所有数最少分成多少个连续段,使得每段的和都 <= k

如果这一次查询无解,输出"Chtholly"

输入描述:

第一行三个数n,m,k
第二行n个数表示这个序列a
之后m行,每行给出两个数l r表示一次询问

输出描述:

输出m行,每行一个整数,表示答案

输入

5 5 7
2 3 2 3 4
3 3
4 4
5 5
1 5
2 4

输出

1
1
1
2
2

sol:初看以为是线段树题,但是肯定会被卡。   我们用st表预处理,st[i][j]表示i点右移1<<j刀的最远距离。  和求LCA的道理一样,只要没到达边界,贪就完事了。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
ll a[maxn]; int st[maxn][],lg[maxn];
int main()
{
int N,M,K,L,R,pos,res;
scanf("%d%d%d",&N,&M,&K);
rep(i,,N) lg[i]=lg[i>>]+;
rep(i,,N) scanf("%lld",&a[i]);
rep(i,,N) a[i]+=a[i-];
rep(i,,) st[N+][i]=N+;
for(int i=N;i>=;i--){
pos=upper_bound(a+,a+N+,a[i-]+K)-a;
st[i][]=pos;
rep(j,,) st[i][j]=st[st[i][j-]][j-];
}
rep(i,,M){
scanf("%d%d",&L,&R);
pos=L; res=;
for(int j=lg[R-L+];j>=;j--) {
if(st[pos][j]<=R) pos=st[pos][j],res+=(<<j);
}
if(st[pos][]<=R) puts("Chtholly");
else printf("%d\n",res+);
}
return ;
}

来自WXK更加NB的做法,目前时间上RK1。

先不考虑K的限制:对于每个点L,我们找到右边界R,[L,R),连边L->R,表示从L出发,最多走到R-1,下一步的起点是R。 然后倒着建树,父亲唯一的,对应的是下一步。   得到dep,得到dfs序。  那么我们dep做差就能逼近答案。   (边--对应了区间划分)

dep做差的前提是我们选择的参照物一致,都是树根,但并非询问的L或者R,会导致答案可能多1,所以我们应该靠齐参照物L,那么我们还要找到L对应到dep[R]的那一层的祖先(这里保存了每一层的节点,利用dfs序找),看它的位置是否包括了R,不包括的话,答案-1。

(由于K的存在,实际操作的是一个森林。

(道理就是一个尺子,量长度,向下取整。 如果我以[0,1]作为起点,答案可能+1,可能是正确的,逼近了这个答案后去验证。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
const int maxn=1e6+;
int a[maxn],dep[maxn],dfn[maxn],To[maxn];
int pre[maxn],tot; ll sum[maxn];
vector<int>G[maxn],C[maxn]; //G保存树,C保存每一层。
void dfs(int u,int f){
dep[u]=dep[f]+; dfn[u]=++tot; To[tot]=u;
C[dep[u]].push_back(tot);
for(int i=;i<G[u].size();i++) dfs(G[u][i],u);
}
int Ac(){
int N,Q,K,L,R;
scanf("%d%d%d",&N,&Q,&K);
rep(i,,N) scanf("%d",&a[i]); a[N+]=K+;
rep(i,,N+) pre[i]=pre[i-]+(a[i]>K), sum[i]=sum[i-]+a[i];
int now=N+;
for(int i=N;i>=;i--){
if(a[i]>K) { now=i; continue;}
int pos=upper_bound(sum+,sum+N+,sum[i-]+K)-sum;
pos=min(pos,now); G[pos].push_back(i);
}
for(int i=N+;i>=;i--) if(a[i]>K) dfs(i,i+);
while(Q--){
scanf("%d%d", &L, &R);
if(pre[R]-pre[L-]!=){
puts("Chtholly");
continue;
}
int res=dep[L]-dep[R]+;
int pos=upper_bound(C[dep[R]].begin(),C[dep[R]].end(),dfn[L])-C[dep[R]].begin();
if(To[C[dep[R]][pos-]]>R) res--;
printf("%d\n",res);
}
return ;
}
int main(){
Ac();
return ;
}

牛客82-B:区间的连续段 (ST表,贪心)(WXK牛逼)的更多相关文章

  1. 牛客练习赛14B 区间的连续段

    题目链接 点我跳转 题目大意 给定一个长度为 \(N\) 的序列 \(A\) 和一个常数 \(K\) 有 \(M\) 次询问 每次询问查询一个区间 \([L , R]\) 内所有数最少分成多少个连续段 ...

  2. 区间的连续段~ST表(模板题)

    链接:https://www.nowcoder.com/acm/contest/82/B来源:牛客网 时间限制:C/C++ 7秒,其他语言14秒 空间限制:C/C++ 262144K,其他语言5242 ...

  3. 牛客练习赛14 B 区间的连续段 (倍增)

    链接:https://ac.nowcoder.com/acm/contest/82/B来源:牛客网 区间的连续段 时间限制:C/C++ 7秒,其他语言14秒 空间限制:C/C++ 262144K,其他 ...

  4. HDU1556 Color the ball & 牛客 contest 135-I 区间 [差分标记]

    一.差分标记介绍 差分标记用来解决针对区间(修改-查询)的问题,复杂度比线段树要更低.推荐这个博客. 例如,给数组中处于某个区间的数进行加减操作,然后查询某个位置上数的变化值. 二.HDU1556 C ...

  5. P2486 [SDOI2011]染色(树剖)区间覆盖+区间的连续段

    https://www.luogu.org/problemnew/show/P2486 值的一看https://www.cnblogs.com/Tony-Double-Sky/p/9283262.ht ...

  6. 牛客练习赛16 A 字典序最大的子序列【贪心】

    链接:https://www.nowcoder.com/acm/contest/84/A 来源:牛客网 [出处]:http://codeforces.com/contest/196/problem/A ...

  7. hdu 2871 Memory Control (区间合并 连续段的起始位置 点所属段的左右端点)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2871 题意: 四种操作: 1.Reset  清空所有内存2.New x  分配一个大小为x的内存块返回,返 ...

  8. 牛客多校第八场 G Gemstones 栈/贪心

    题意: 对于一个序列,把可以把连着三个相同的字母拿走,问最多拿走多少组. 题解: 直接模拟栈,三个栈顶元素相同则答案+1,并弹出栈 #include<bits/stdc++.h> usin ...

  9. [暴力+前缀和]2019牛客暑期多校训练营(第六场)Upgrading Technology

    链接:https://ac.nowcoder.com/acm/contest/886/J来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

随机推荐

  1. Echartjs axis.getAxesOnZeroOf is not a function

    该问题已经解决,下面是解决思路! 问题描述: axis.getAxesOnZeroOf is not a function 使用echart 出现报这句错误,请求解决方案! 问题原因: 我给坐标设置了 ...

  2. 从Asp .net到Asp core (第二篇)《Asp Core 的生命周期》

    前面一篇文章简单回顾了Asp .net的生命周期,也简单提到了Asp .net与Asp Core 的区别,我们说Asp Core不在使用Asp.netRuntime,所以它也没有了web程序生命周期中 ...

  3. 程序员生存之道,多写bug!

    1.代码写得好,bug少,看起来就像闲人. 2.注释多,代码清晰,任何人接手非常方便,看起来谁都都可以替代. 3.代码写得烂,每天风风火火改bug,各种救火,解决各种线上重大问题,于是顺理成章为公司亮 ...

  4. 2. 执行Spark SQL查询

    2.1 命令行查询流程 打开Spark shell 例子:查询大于21岁的用户 创建如下JSON文件,注意JSON的格式: {"name":"Michael"} ...

  5. android使用http3

    http3的github地址: https://github.com/cloudflare/quiche

  6. jquery获取窗口和文档的高度和宽度

    整个可视区域的宽度和高度(会随着浏览器窗口大小改变而改变): $(window).width()和$(window).height() 整个文档的宽度和高度(不变): $(docoument).wid ...

  7. Euraka适合初学者的简单小demo

    1. 创建父工程:父工程的的打包形式该为pom,删除其余无关的文件 修改父工程的pom文件内容如下: <?xml version="1.0" encoding="U ...

  8. ZeroMQ自查手册

    简介 ZMQ (以下 ZeroMQ 简称 ZMQ)是一个简单好用的传输层,像框架一样的一个 socket library,他使得 Socket 编程更加简单.简洁和性能更高.是一个消息处理队列库,可在 ...

  9. CentOS 7 - 安装PostgreSQL

    一,用yum安装PostgreSQL . 选择安装版本和服务器平台后,执行安装命令,例如我要安装是9.6版本,平台是CentOS 7. https://www.postgresql.org/downl ...

  10. 一段让人瑟瑟发抖的ABAP代码

    昨天11月1日是万圣节,Jerry在继续忙着调研SAP Commerce Cloud里的产品主数据管理.晚上回家到SAP国外的社交媒体上一看,好热闹啊.国外的SAP从业者们纷纷以各种各样的方式庆祝万圣 ...