来源:牛客网:

题目描述
给你一个长为n的序列a和一个常数k

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

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

题解:

图片说明

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;

const int maxn =1e6+10;
typedef long long ll;
ll sum[maxn],f[maxn][22];

int main() {
    ll n,m,k;
    scanf("%lld%lld%lld",&n,&m,&k);
    for (int i=1 ;i<=n ;i++){
        ll x;
        scanf("%lld",&x);
        sum[i]=sum[i-1]+x;
    }
    for (int i=0 ;i<=21 ;i++ ) f[n+1][i]=n+1;
    for (int i=n ;i>=1  ;i-- ) {
        f[i][0]=upper_bound(sum+i,sum+n+1,sum[i-1]+k)-sum;
        for (int j=1 ;j<=21 ;j++) {
            f[i][j]=f[f[i][j-1]][j-1];
        }
    }
    while(m--){
        ll  x,y,ans=0;
        scanf("%lld%lld",&x,&y);
        for (int i=21 ;i>=0 ;i--){
            if (f[x][i]<=y) ans+=1<<i,x=f[x][i];
        }
        if (f[x][0]>y) printf("%lld\n",ans+1);
        else printf("Chtholly\n");
    }
    return 0;
}