zoukankan      html  css  js  c++  java
  • SPOJ 1043 Can you answer these queries I

    SPOJ_1043

        今天顿时发现原来GSS系列一共有7道题,这个是其中的一道,只要在网址那改一下GGS*就可以找到其他的题目了。

        这个题目可以用线段树去做,一个可行的思路就是计算出三个标记mc[](当前区间内最大的连续子串和),lc[](从当前区间左端点开始向右的最大的连续子串和),rc[](从当前区间右端点开始的向左的最大的连续子串和)。

        查询的时候利用这三个标记进行计算就可以了。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 50010
    int N, A[MAXD], mc[4 * MAXD], lc[4 * MAXD], rc[4 * MAXD];
    int getmax(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] = getmax(mc[ls], mc[rs]);
        mc[cur] = getmax(mc[cur], rc[ls] + lc[rs]);
        lc[cur] = getmax(lc[ls], A[mid] - A[x - 1] + lc[rs]);
        rc[cur] = getmax(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] - A[x - 1];
            return ;
        }
        build(ls, x, mid);
        build(rs, mid + 1, y);
        update(cur, x, y);
    }
    void init()
    {
        int i;
        A[0] = 0;
        for(i = 1; i <= N; i ++)
        {
            scanf("%d", &A[i]);
            A[i] = A[i - 1] + A[i];
        }
        build(1, 1, N);
    }
    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 = getmax(ans, mc[cur]);
            return flag == -1 ? lc[cur] : rc[cur];
        }
        if(mid >= t)
            return query(ls, x, mid, s, t, -1, ans);
        else if(mid + 1 <= s)
            return query(rs, mid + 1, y, s, t, 1, ans);
        else
        {
            int ln, rn;
            ln = query(ls, x, mid, s, t, 1, ans);
            rn = query(rs, mid + 1, y, s, t, -1, ans);
            ans = getmax(ans, ln + rn);
            if(flag == -1)
                return getmax(lc[ls], A[mid] - A[x - 1] + rn);
            else
                return getmax(rc[rs], A[y] - A[mid] + ln);
        }
    }
    void solve()
    {
        int i, Q, x, y, ans;
        scanf("%d", &Q);
        for(i = 0; i < Q; i ++)
        {
            scanf("%d%d", &x, &y);
            ans = A[x] - A[x - 1];
            query(1, 1, N, x, y, -1, ans);
            printf("%d\n", ans);
        }
    }
    int main()
    {
        while(scanf("%d", &N) == 1)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    自考感悟,话谈备忘录模式
    [每日一题] OCP1z0-047 :2013-07-26 alter table set unused之后各种情况处理
    Java实现 蓝桥杯 算法提高 p1001
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 因式分解
    Java实现 蓝桥杯 算法提高 因式分解
  • 原文地址:https://www.cnblogs.com/staginner/p/2455126.html
Copyright © 2011-2022 走看看