题目描述
给你一个长为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; }