zoukankan      html  css  js  c++  java
  • SPOJ

    题目链接:https://vjudge.net/problem/SPOJ-GSS1

    GSS1 - Can you answer these queries I

    You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defined as follows: 
    Query(x,y) = Max { a[i]+a[i+1]+...+a[j] ; x ≤ i ≤ j ≤ y }. 
    Given M queries, your program must output the results of these queries.

    Input

    • The first line of the input file contains the integer N.
    • In the second line, N numbers follow.
    • The third line contains the integer M.
    • M lines follow, where line i contains 2 numbers xi and yi.

    Output

    Your program should output the results of the M queries, one query per line.

    Example

    Input:
    3 
    -1 2 3
    1
    1 2
    
    Output:
    2

    题意:

    给出一个序列。有m个询问:区间[L,R]里的最大连续和是多少?

    题解:

    1.线段树的结点信息合并。将这n个数按线段树的形式分割下去,然后再从最底层的小区间,往上合并得到大区间:两个对应的小区间有四种合并结果(得到一段连续的区间):1.左连续、右连续、左右不连续、全连续。记录每种合并结果的最大值。

    2.对于询问区间,依旧如普通的查询操作一样,拿到线段树里与对应区间,但是需要注意的是:当询问区间被mid分成两段时,需要单独单出来,然后再尝试将两段进行信息合并。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <vector>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <string>
    11 #include <set>
    12 using namespace std;
    13 typedef long long LL;
    14 const double EPS = 1e-8;
    15 const int INF = 2e9;
    16 const LL LNF = 2e18;
    17 const int MAXN = 5e4+10;
    18 
    19 struct node
    20 {
    21     int a[4];
    22 };
    23 node sum[MAXN<<2];
    24 
    25 /*
    26     0:两边不连续
    27     1:左连续
    28     2:右连续
    29     3:全连续
    30 */
    31 void push_up(int fa[], int s1[], int s2[])
    32 {
    33     fa[0] = max(max(s1[0], s2[0]),max(max(s1[2],s2[1]), s1[2]+s2[1]));
    34     fa[1] = max(max(s1[1],s1[3]), s1[3]+s2[1]);
    35     fa[2] = max(max(s2[2],s2[3]), s1[2]+s2[3]);
    36     fa[3] = s1[3] + s2[3];
    37 }
    38 
    39 void build(int u, int l, int r)
    40 {
    41     if(l==r)
    42     {
    43         scanf("%d", &sum[u].a[3]);  //只有一个点,当然是全连续
    44         sum[u].a[0] = sum[u].a[1] = sum[u].a[2] = -15007;   //其他情况设为不可能
    45         return;
    46     }
    47 
    48     int mid = (l+r)>>1;
    49     build(u*2, l, mid);
    50     build(u*2+1, mid+1, r);
    51     push_up(sum[u].a, sum[u*2].a, sum[u*2+1].a);
    52 }
    53 
    54 node query(int u, int l, int r, int x, int y)
    55 {
    56     if(x<=l && r<=y)
    57         return sum[u];
    58 
    59     int mid = (l+r)>>1;
    60     node ret;
    61     if(y<=mid)  //询问区间在左边
    62         ret = query(u*2, l, mid, x, y);
    63     else if(x>=mid+1)   //询问区间在右边
    64         ret = query(u*2+1, mid+1, r, x, y);
    65     else    //询问区间被分割成两段,因而还要调用push_up尝试将两子区间合并
    66     {
    67         node t1 = query(u*2, l, mid, x, mid);
    68         node t2 = query(u*2+1, mid+1, r, mid+1, y);
    69         push_up(ret.a, t1.a, t2.a);
    70     }
    71     return ret;
    72 }
    73 
    74 int main()
    75 {
    76     int n, m;
    77     scanf("%d", &n);
    78     build(1,1,n);
    79     scanf("%d", &m);
    80     while(m--)
    81     {
    82         int l, r;
    83         scanf("%d%d", &l,&r);
    84         node ret = query(1,1,n,l,r);
    85         int t1 = max(ret.a[0], ret.a[1]);   //取四种连续情况的最大值
    86         int t2 = max(ret.a[2], ret.a[3]);
    87         printf("%d
    ", max(t1,t2));
    88     }
    89 }
    View Code
  • 相关阅读:
    Mac Finder 里新建文本
    SourceTree 无法查看组织仓库
    Android Gradle 指定 Module 打包
    Mac 下安装安卓 apk 文件
    Android 瘦身之道 ---- so文件
    Android Google AdMob 广告接入示例
    Java 垃圾回收(GC) 泛读
    [麻雀虽小]记 简易Markdown阅读器 开发全过程
    Git 版本回滚
    线程与进程的区别及其通信方式
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8641783.html
Copyright © 2011-2022 走看看