zoukankan      html  css  js  c++  java
  • Sicily 1800. Sequence

    1800. Sequence

    Constraints

    Time Limit: 1 secs, Memory Limit: 32 MB

    Description

    Given a sequence S of n numbers and two length bounds L and U.

    Your task is to write a program to find a segment S[i], S[i+1], …, S[j] with minimum sum over all segments of S with length at least L and at most U.

    Input

    The input consists of multiple datasets. The end of the input is indicated by a line containing a zero.

    The format of each dataset is as follows.

    n

    L U

    SS2 … Sn

    Here, all data items are integers. n is the length of the sequence (N≤32767). L and Uare two length bounds where LUS1, S2, …, Sn are the sequence of n numbers.

    Output

    For each dataset, output the minimum sum of segment, in a separate line.

    Sample Input

    9
    2 8
    -3 2 -2 5 -4 1 -2 3 1
    0

    Sample Output

    -5

    Hint

    the segment is -4 1 -2.

    建立一棵线段树存储前缀和的最大值,注意从 0 开始

    枚举区间右端点 i,查询 max(0,i-u) 到 i 范围内前缀和的最大值,用 i 处的前缀和减去它就是所求的最小值

    其实一开始还想歪用 O(nlogn) 的分治法求最小连续子段和,枚举区间左右端点……这样就成了 O(n^2) 了(

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #define rep(i,l,r) for(int i = l; i <= r; i++)
     6 #define clr(x,y) memset(x,y,sizeof(x))
     7 #define travel(x) for(Edge *p = last[x]; p; p = p -> pre)
     8 using namespace std;
     9 const int maxn = 32800;
    10 inline int read(){
    11     int ans = 0, f = 1; char c = getchar();
    12     for(; !isdigit(c); c = getchar()) if (c == '-') f = -1;
    13     for(; isdigit(c); c = getchar()) ans = ans * 10 + c - '0';
    14     return ans * f;
    15 }
    16 struct Node{
    17     int l, r, s;
    18 }t[maxn<<2];
    19 int n, l, u, s[maxn];
    20 void build(int u,int v,int w){
    21     t[w].l = u; t[w].r = v;
    22     if (u == v){
    23         t[w].s = s[u]; return;
    24     }
    25     int mid = (u + v) >> 1;
    26     build(u,mid,w<<1); build(mid+1,v,w<<1|1);
    27     t[w].s = max(t[w<<1].s, t[w<<1|1].s);
    28 }
    29 int query(int u,int v,int w){
    30     if (t[w].l == u && t[w].r == v) return t[w].s;
    31     int mid = (t[w].l + t[w].r) >> 1;
    32     if (v <= mid) return query(u,v,w<<1);
    33     else if (u > mid) return query(u,v,w<<1|1);
    34     else return max(query(u,mid,w<<1), query(mid+1,v,w<<1|1));
    35 }
    36 void work(){
    37     l = read(); u = read();
    38     s[0] = 0; rep(i,1,n) s[i] = s[i-1] + read();
    39     build(0,n,1);
    40     int ans = 0x7fffffff;
    41     rep(i,l,n) ans = min(ans, s[i] - query(max(0,i-u),i-l,1));
    42     printf("%d
    ",ans);
    43 }
    44 int main(){
    45     n = read();
    46     while (n){
    47         work(); n = read();
    48     } 
    49     return 0;
    50 }
    View Code
  • 相关阅读:
    【LeetCode】1248. 统计「优美子数组」
    【LeetCode】200. 岛屿数量
    【LeetCode】53. 最大子序和
    【剑指Offer】面试题42. 连续子数组的最大和
    【剑指Offer】面试题57. 和为s的两个数字
    【LeetCode】55. 跳跃游戏
    【LeetCode】56. 合并区间
    简历HTML网页版
    关于新建Eclipse新建一个WEB项目后创建一个jsp文件头部报错问题?
    jquery选择器 看这个链接吧!2017.6.2
  • 原文地址:https://www.cnblogs.com/jimzeng/p/sicily1800.html
Copyright © 2011-2022 走看看