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

简介: 牛客练习赛14 B.区间的连续段(前缀和 倍增)

原题链接

题意:

给你一个长为n的序列a和一个常数k。有m次询问,每次查询一个区间[ l , r ]内所有数最少分成多少个连续段,使得每段的和都< = k。如果这一次查询无解,输出" C h t h o l l y "。

思路:

先考虑简化版:给定一个序列和k,问将该序列最少分成多少个连续段,使得每段的和都< = k。

从前向后枚举,对于每次结果都贪心的考虑,如果当前和大于k就重新开一段。

也就是说需要处理的就是,对于每个点能够到达的最远的点。

回到这个题,类比的处理一下。但是加了区间限制之后,最远的点不一定在区间里,所以略微变形一下:维护d p [ i ] [ j ]表示从点i开始,分成2 j段,最远能够到达的位置的下一个点。

由于2 j = 2 j − 1 + 2 j − 1,所以d p [ i ] [ j ] = d p [ d p [ i ] [ j − 1 ] ] [ j − 1 ]

对于d p [ i ] [ 0 ] = x,找一个位置[ i , x − 1 ]使得该段的和恰好小于k kk;s u m [ i ] sum[i]sum[i]表示a aa的前缀和。也就是说s u m [ x − 1 ] − s u m [ i − 1 ] < k , s u m [ x − 1 ] < s u m [ i − 1 ] + k sum[x-1]-sum[i-1]

对于查询:" C h t h o l l y "的情况就是a [ i ] > k , l < = i < = r。用t o t [ i ]表示前i个数中> k的数的个数,每次查询t o t [ r ] − t o t [ l − 1 ],如果大于0,就是" C h t h o l l y "

对于其他情况,从大到小枚举,类似二进制拆分的原理。[ l , s t [ l ] [ i ] )表示将区间分成了2 i段,所以答案要加2 i 。

注意d p维护的是下一个位置,所以最后那段是不计算的,要额外再+ 1

代码:

const int maxn=1000000+7;
ll n,m,k,a[maxn],tot[maxn];
ll dp[maxn][25];
ll sum[maxn];
int main(){
  n=read,m=read,k=read;
  rep(i,1,n){
    a[i]=read;
    sum[i]=sum[i-1]+a[i];
    if(a[i]>k) tot[i]=tot[i-1]+1;
    else tot[i]=tot[i-1];
  }
  rep(i,1,n){
    dp[i][0]=upper_bound(sum+1,sum+1+n,sum[i-1]+k)-(sum+1)+1;
  }
  for(int j=1;(1<<j)<n;j++)
    for(int i=1;i+(1<<j)<=n;i++){
      dp[i][j]=dp[dp[i][j-1]][j-1];
    }
  while(m--){
    int l=read,r=read;
    if(tot[r]-tot[l-1]>0){
      puts("Chtholly");
    }
    else{
      int res=1;
      for(int i=20;dp[l][0]<=r;i--)
        if(dp[l][i]&&dp[l][i]<=r)
          l=dp[l][i],res+=(1<<i);
      cout<<res<<endl;
    }
  }
  return 0;
}


目录
相关文章
|
6月前
【每日一题Day179】LC1157子数组中占绝大多数的元素 | 线段树
【每日一题Day179】LC1157子数组中占绝大多数的元素 | 线段树
49 0
|
5月前
|
算法 测试技术 程序员
力扣经典150题第三十题:长度最小的子数组
力扣经典150题第三十题:长度最小的子数组
27 1
|
6月前
|
算法
求连续整数的阶层的和,时间复杂程度为O(n)的解法
求连续整数的阶层的和,时间复杂程度为O(n)的解法
|
6月前
|
人工智能 算法
前缀和算法题(区间次方和、小蓝平衡和、大石头的搬运工、最大数组和)
前缀和算法题(区间次方和、小蓝平衡和、大石头的搬运工、最大数组和)
|
12月前
|
人工智能 算法
代码随想录算法训练营第三十五天 | LeetCode 435. 无重叠区间、763. 划分字母区间、56. 合并区间
代码随想录算法训练营第三十五天 | LeetCode 435. 无重叠区间、763. 划分字母区间、56. 合并区间
61 0
|
12月前
|
算法 索引
代码随想录算法训练营第二天 |977.有序数组平方,209.长度最小的字数组,59.螺旋矩阵
代码随想录算法训练营第二天 |977.有序数组平方,209.长度最小的字数组,59.螺旋矩阵
|
人工智能
蓝桥 k倍区间 (前缀和)
蓝桥 k倍区间 (前缀和)
|
算法 测试技术 Android开发
LeetCode 周赛上分之旅 #40 结合特征压缩的数位 DP 问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
67 0
[leetcode] 1675. 数组的最小偏移量 | 思维贪心 | 大疆笔试题
[leetcode] 1675. 数组的最小偏移量 | 思维贪心 | 大疆笔试题
111 0
|
人工智能 算法 vr&ar
每日算法系列【LeetCode 1004】最大连续1的个数 III
每日算法系列【LeetCode 1004】最大连续1的个数 III