zoukankan      html  css  js  c++  java
  • SPOJ 2916 Can you answer these queries V

    SPOJ_2916

        这个题目需要分情况讨论一下,如果y1<x2,那么就是前面区间的一个后缀,加上后面区间的一个前缀,再加上中间的部分,如果y1>=x2,则根据位置的不同又可以另分三种情况,逐一讨论并更新最优解即可。

        分析之后就发现,在线段树的基础上写两个查询函数即可,一个就是和SPOJ_1716的GSS1那样功能的函数(在我的程序里面对应的是query这个函数),另一个是可以求一个区间最大的前缀和或者后缀和的函数(在我的程序里面对应的是Search这个函数)。

    #include<stdio.h>
    #include<string.h>
    #define INF 0x3f3f3f3f
    #define MAXD 10010
    int N, A[MAXD], a[MAXD], mc[4 * MAXD], lc[4 * MAXD], rc[4 * MAXD];
    int Max(int x, int y)
    {
        return x > y ? x : y;
    }
    void update(int cur, int x, int y)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1;
        mc[cur] = Max(mc[ls], mc[rs]);
        mc[cur] = Max(mc[cur], rc[ls] + lc[rs]);
        lc[cur] = Max(lc[ls], A[mid] - A[x - 1] + lc[rs]);
        rc[cur] = Max(rc[rs], A[y] - A[mid] + rc[ls]);
    }
    void build(int cur, int x, int y)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1;
        if(x == y)
        {
            mc[cur] = lc[cur] = rc[cur] = a[x];
            return ;
        }
        build(ls, x, mid);
        build(rs, mid + 1, y);
        update(cur, x, y);
    }
    int query(int cur, int x, int y, int s, int t, int flag, int &ans)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1;
        if(x >= s && y <= t)
        {
            ans = Max(ans, mc[cur]);
            if(flag == 0)
                return lc[cur];
            else
                return rc[cur];
        }
        if(mid >= t)
            return query(ls, x, mid, s, t, 0, ans);
        else if(mid + 1 <= s)
            return query(rs, mid + 1, y, s, t, 1, ans);
        int ln, rn;
        ln = query(ls, x, mid, s, t, 1, ans);
        rn = query(rs, mid + 1, y, s, t, 0, ans);
        ans = Max(ans, ln + rn);
        if(flag == 0)
            return Max(lc[ls], A[mid] - A[x - 1] + rn);
        else
            return Max(rc[rs], A[y] - A[mid] + ln);
    }
    void Search(int cur, int x, int y, int s, int t, int flag, int &ans)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1;
        if(x >= s && y <= t)
        {
            if(flag == 0)
                ans = Max(ans, A[x - 1] - A[s - 1] + lc[cur]);
            else
                ans = Max(ans, A[t] - A[y] + rc[cur]);
            return ;
        }
        if(mid >= s)
            Search(ls, x, mid, s, t, flag, ans);
        if(mid + 1 <= t)
            Search(rs, mid + 1, y, s, t, flag, ans);
    }
    void init()
    {
        int i, j, k;
        scanf("%d", &N);
        A[0] = 0;
        for(i = 1; i <= N; i ++)
        {
            scanf("%d", &a[i]);
            A[i] = A[i - 1] + a[i];
        }
        build(1, 1, N);
    }
    void solve()
    {
        int i, q, ans, t1, t2, x1, y1, x2, y2;
        scanf("%d", &q);
        for(i = 0; i < q; i ++)
        {
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
            if(y1 < x2)
            {
                t1 = t2 = -INF;
                Search(1, 1, N, x1, y1, 1, t1);
                Search(1, 1, N, x2, y2, 0, t2);
                printf("%d\n", t1 + t2 + A[x2 - 1] - A[y1]);
            }
            else
            {
                ans = -INF;
                query(1, 1, N, x2, y1, 0, ans);
                t1 = t2 = -INF;
                Search(1, 1, N, x1, y1, 1, t1);
                Search(1, 1, N, y1, y2, 0, t2);
                ans = Max(ans, t1 + t2 - a[y1]);
                t1 = t2 = -INF;
                Search(1, 1, N, x1, x2, 1, t1);
                Search(1, 1, N, x2, y2, 0, t2);
                ans = Max(ans, t1 + t2 - a[x2]);
                printf("%d\n", ans);
            }
        }
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t --)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    远程过程调用RPC
    CAP原理
    2021/03/08阿里在线笔试问题总结
    水容器问题
    rand5生成rand3和rand7
    二维数组查找K(Go语言)
    判别IP为IPV4或者IPV6 (Go语言)
    路径总和(Go)
    合并K个升序链表(Go)
    delphi idhttp提交网址包含中文
  • 原文地址:https://www.cnblogs.com/staginner/p/2529078.html
Copyright © 2011-2022 走看看