• 区间的连续段~ST表(模板题)


    链接:https://www.nowcoder.com/acm/contest/82/B
    来源:牛客网

    时间限制:C/C++ 7秒,其他语言14秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    题目描述

    给你一个长为n的序列a和一个常数k

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

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

    输入描述:

    第一行三个数n,m,k
    第二行n个数表示这个序列a
    之后m行,每行给出两个数l r表示一次询问

    输出描述:

    输出m行,每行一个整数,表示答案
    示例1

    输入

    5 5 7
    2 3 2 3 4
    3 3
    4 4
    5 5
    1 5
    2 4

    输出

    1
    1
    1
    2
    2

    备注:

    对于100%的数据,1 <= n , m <= 1000000 , 1 <= ai , k <= 1000000000

    这题需要用到倍增算法,倍增博大精深啊。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<queue>
     7 using namespace std;
     8 
     9 const int maxn =1e6+10;
    10 typedef long long ll;
    11 ll sum[maxn],f[maxn][22];
    12 
    13 int main() {
    14     ll n,m,k;
    15     scanf("%lld%lld%lld",&n,&m,&k);
    16     for (int i=1 ;i<=n ;i++){
    17         ll x;
    18         scanf("%lld",&x);
    19         sum[i]=sum[i-1]+x;
    20     }
    21     for (int i=0 ;i<=21 ;i++ ) f[n+1][i]=n+1;
    22     for (int i=n ;i>=1  ;i-- ) {
    23         f[i][0]=upper_bound(sum+i,sum+n+1,sum[i-1]+k)-sum;
    24         for (int j=1 ;j<=21 ;j++) {
    25             f[i][j]=f[f[i][j-1]][j-1];
    26         }
    27     }
    28     while(m--){
    29         ll  x,y,ans=0;
    30         scanf("%lld%lld",&x,&y);
    31         for (int i=21 ;i>=0 ;i--){
    32             if (f[x][i]<=y) ans+=1<<i,x=f[x][i];
    33         }
    34         if (f[x][0]>y) printf("%lld
    ",ans+1);
    35         else printf("Chtholly
    ");
    36     }
    37     return 0;
    38 }
  • 相关阅读:
    Solr简介
    儿童节快乐
    添加新的内容分类
    weka
    Junit测试样例
    Linux MySQL单实例源码编译安装5.5.32
    perconatoolkit 工具集安装
    Linux MySQL单实例源码编译安装5.6
    MySQL 开机自启动
    mysql5.6之前需要账号的安全加固
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/8728277.html
Copyright © 2020-2023  润新知