Enlace del título
Tema:
Le da una secuencia a de longitud ny una constante k
Hay m consultas, cada vez que se pregunta cuántos números consecutivos dentro de un rango [l, r] se dividen en al menos cuántos segmentos consecutivos, de modo que la suma de cada segmento es <= k
Si la consulta no tiene solución esta vez, envíe "Chtholly"
Práctica: Punto de conocimiento: Algoritmo de multiplicación.
Sea f [i] [j] el subíndice del subíndice i que se puede dividir en 2 ^ j grupos, entonces el estado inicial es dp [i] [0] igual al intervalo de i a dp [i] [0] Solo mayor que k
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int n,m;
ll s;
ll fa[N][22];
ll mx[4*N],pre[N],a[N];
void build(int id,int l,int r)
{
if(l == r){
mx[id] = a[l];
return ;
}
int mid = l + r >> 1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
mx[id] = max(mx[id<<1] , mx[id<<1|1]);
}
ll qu(int id,int l,int r,int ql,int qr)
{
if(ql <= l && r <= qr) return mx[id];
int mid = l+r>>1;
ll res = 0;
if(ql <= mid) res = qu(id<<1,l,mid,ql,qr);
if(qr > mid) res = max(res , qu(id<<1|1,mid+1,r,ql,qr));
return res;
}
int main()
{
cin>>n>>m>>s;
for(int i = 1;i <= n; ++i) {
scanf("%lld",&a[i]);
pre[i] = pre[i-1] + a[i];
}
build(1,1,n);
for(int i = n;i >= 1; --i){
fa[i][0]=upper_bound(pre+i,pre+n+1,pre[i-1]+s)-pre;
}
for(int k=1;k<=20;++k)
for(int i=n;i>=1;--i)
fa[i][k]=fa[fa[i][k-1]][k-1];
while(m--){
int l,r;
scanf("%d%d",&l,&r);
if(qu(1,1,n,l,r) > s){puts("Chtholly");continue;}
int x=l;
int ans=0;
for(int k=19;k>=0;--k){
if(fa[x][k]&&fa[x][k]<=r) {
x=fa[x][k],ans=(ans+(1<<k));
}
}
if(fa[x][0]>r) ans++;
printf("%d\n",ans);
}
return 0;
}