​题目传送门​​​ dp[i][j]表示从位置 i 开始分 2^j 段的 结束点+1的位置
再进行倍增打表即可,具体看代码

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=1000000+100;

int dp[maxn][25];
ll sum[maxn];

int main(){

int n,m;
ll k;
scanf("%d%d%lld",&n,&m,&k);
sum[0]=0;
for(int i=1;i<=n;i++) scanf("%lld",&sum[i]),sum[i]+=sum[i-1];
for(int i=0;i<=21;i++) dp[n+1][i]=n+1;
for(int i=n;i>=1;i--){

dp[i][0]=upper_bound(sum+1,sum+1+n,sum[i-1]+k)-sum;
for(int j=1;j<=21;j++) dp[i][j]=dp[dp[i][j-1]][j-1];
}
while(m--){

int l,r;
scanf("%d%d",&l,&r);
ll cnt=0;
for(int i=21;i>=0;i--){

if(dp[l][i]<=r) cnt+=(1<<i),l=dp[l][i];
}
if(dp[l][0]>r) printf("%lld\n",cnt+1);
else printf("Chtholly\n");
}
}