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

    思路:用TREE记录节点的最大连续和,LEF记录左边开始的最大连续和,RIG记右边开始的最大连续和

    然后处理的时候就是比较左边最大,右边最大  中间区间的问题

    其中这个query 只能膜拜了。。。

    大大缩减了时间。放弃治疗的我只会用三个函数

    传参就要传出翔。

    flag == -1表示要左边最大

    flag == 1 表示要右边最大

    然后ans在找到的区间的同时进行比较。

    我已可入灵魂

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define MAXN 50005
    #define lson num<<1,s,mid
    #define rson num<<1|1,mid+1,e
    
    using namespace std;
    
    int tree[MAXN<<2];
    int lef[MAXN<<2];
    int rig[MAXN<<2];
    int X[MAXN]={0};
    int n;
    int cnt;
    
    inline void pushup(int num,int s,int e)
    {
        int mid=(s+e)>>1;
    
        lef[num]=max(lef[num<<1],X[mid]-X[s-1]+lef[num<<1|1]);
        rig[num]=max(rig[num<<1|1],X[e]-X[mid]+rig[num<<1]);
        tree[num]=max(lef[num<<1|1]+rig[num<<1],max(tree[num<<1],tree[num<<1|1]));
    }
    
    
    void build(int num,int s,int e)
    {
        if(s==e)
        {
            scanf("%d",&tree[num]);
            lef[num]=rig[num]=tree[num];
            X[cnt]=X[cnt-1]+tree[num];
            cnt++;
            return;
        }
        int mid=(s+e)>>1;
    
        build(num<<1,s,mid);
        build(num<<1|1,mid+1,e);
        pushup(num,s,e);
    }
    
    int query(int num, int s, int e, int l, int r, int flag, int &ans)
    {
        int mid = (s+e)>>1;
        if(s >= l && e <= r)
        {
            ans = max(ans, tree[num]);
            return flag == -1 ? lef[num] : rig[num];
        }
        if(mid >= r)
            return query(num<<1, s, mid, l, r, -1, ans);
        else if(mid  < l)
            return query(num<<1|1, mid + 1, e, l, r, 1, ans);
        else
        {
            int ln, rn;
            ln = query(num<<1, s, mid, l, r, 1, ans);
            rn = query(num<<1|1, mid + 1, e, l, r, -1, ans);
            ans = max(ans, ln + rn);
            if(flag == -1)
                return max(lef[num<<1], X[mid] - X[s - 1] + rn);
            else
                return max(rig[num<<1|1], X[e] - X[mid] + ln);
        }
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            cnt=1;
            X[0]=0;
            build(1,1,n);
    
            int m;
            scanf("%d",&m);
            while(m--)
            {
                int aa,bb;
                scanf("%d%d",&aa,&bb);
                int ans=X[aa]-X[aa-1];
                query(1,1,n,aa,bb,-1,ans);
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    
    /*
    8
    -1 5 -6 7 -4 8 -2 7
    999
    */
    


  • 相关阅读:
    第二次作业循环语句
    c语言01次作业分支,顺序结构
    PAT 1027. Colors in Mars
    PAT 1026 Table Tennis
    PAT 1035 Password
    PAT 1038. Recover the Smallest Number
    PAT 1028 List Sorting (25)
    PAT 1041 Be Unique (20)
    PAT 1025 PAT Ranking
    1037. Magic Coupon
  • 原文地址:https://www.cnblogs.com/pangblog/p/3255893.html
Copyright © 2011-2022 走看看