求助!!!(区间最大子段和)
  • 板块题目总版
  • 楼主llamn
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/6/22 15:26
  • 上次更新2024/6/22 18:02:21
查看原帖
求助!!!(区间最大子段和)
1038651
llamn楼主2024/6/22 15:26

题意:

给出nn个数,查询mm次给出的ll和rr间的最大字段和
对于每个查询,输出《ii,jj》,ss,表示ii到jj间的和为ss,l≤i≤j≤rl≤i≤j≤r
《如果有多组解,则输出i最小的,如果i也相等,则输出j最小的解。》

线段树代码:

#include <bits/stdc++.h> 
#define _eggy_ using 
#define _party_ namespace
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define TLE() while(1){int zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz = 0;}
//更新的七种模式。命名规则:前为所求值,后为求值方法
#define ls_l 'l' //以ls = ls_l求得ls
#define ls_r 'L' //以ls = sum_l + ls_r求得ls
#define rs_r 'r' //以rs = rs_r求得rs
#define rs_l 'R' //以rs = sum_r + rs_l求得rs
#define s_l 's' //以s = s_l求得s
#define s_r 'S' //以s = s_r求得s
#define s_mid 'm' //以s = ls_r + rs_l求得s
_eggy_ _party_ std;

int n,m,q,i,j,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30;
struct dzpd
{
    int l,r,sum, //sum:区间所有元素的和
    ls,   lsr,  
    rs,rsl   ,
    s,sl,sr; // s:区间最大子段和。sl和sr:当前求出答案的左右端点
};
struct dzpd tr[400050];
struct dzpd t31,t32,t33,t34,t35,t36,t37,t38,t39,t40;
int a[100010];
void bd(int x, int l, int r);
struct dzpd getsum(int x);
void gx(struct dzpd &x, char mode_cyy, struct dzpd l, struct dzpd r);

int main()
{
    scanf("%d%d",&n,&m);
    for (i = 1; i <= n; i++) scanf("%d ",&a[i]);
    bd(1,1,n);
    t31 = getsum(1);
    for (i = 1; i <= m; i++)
    {
        scanf("%d %d",&t1,&t2);
        t31 = getsum(1);
        printf("%d %d %d\n",t31.sl,t31.sr,t31.s);
    }
    return 0;
}
void bd(int x, int l, int r)
{
    tr[x].l = l; tr[x].r = r;
    if (l == r)
    {
        tr[x].sum = tr[x].ls = tr[x].rs = tr[x].s = a[l];
        tr[x].lsr = tr[x].rsl = tr[x].sl = tr[x].sr = l;
        return;
    }
    tr[x].ls = tr[x].rs = tr[x].s = -1 * 'e' * 'g' * 'g' * 'y';
    bd(x*2,l,(l+r)/2);
    bd(x*2+1,(l+r)/2+1,r);
    tr[x].sum = tr[x*2].sum + tr[x*2+1].sum;
    //维护优先级:答案 > l > r
    //————————————————————————————————————————————
    //求解ls:
    if (tr[x].ls < tr[x*2].ls) gx(tr[x],ls_l,tr[x*2],tr[x*2+1]); //第一优先级:答案
    if (tr[x].ls < tr[x*2].sum + tr[x*2+1].ls) gx(tr[x],ls_r,tr[x*2],tr[x*2+1]);
    if (tr[x*2].ls == tr[x*2].sum + tr[x*2+1].ls) //第二优先级:l
    {
        gx(tr[x],ls_l,tr[x*2],tr[x*2+1]);
        // 由性质得,ls_l的l与sum_l+ls_r的l相同
        //第三优先级:r
        //ls_l的r一定在ls_r之左
    }
    //求解rs:
    if (tr[x].rs < tr[x*2+1].rs) gx(tr[x],rs_r,tr[x*2],tr[x*2+1]);
    if (tr[x].rs < tr[x*2+1].sum + tr[x*2].rs) gx(tr[x],rs_l,tr[x*2],tr[x*2+1]);
    if (tr[x*2+1].rs == tr[x*2+1].sum + tr[x*2].rs) gx(tr[x],rs_l,tr[x*2],tr[x*2+1]);
                                      //判断第二优先级即可
    //求解s:
    if (tr[x].s < tr[x*2].s) gx(tr[x],s_l,tr[x*2],tr[x*2+1]);
    if (tr[x].s < tr[x*2].rs + tr[x*2+1].ls) gx(tr[x],s_mid,tr[x*2],tr[x*2+1]);
    if (tr[x].s < tr[x*2+1].s) gx(tr[x],s_r,tr[x*2],tr[x*2+1]);
    // 从l上计算,s_l的l <= s_mid的l <= s_r的l
    if ((tr[x*2].s == tr[x*2+1].s) && (tr[x*2+1].s == tr[x*2].rs + tr[x*2+1].ls))
        gx(tr[x],s_l,tr[x*2],tr[x*2+1]);
    else if((tr[x*2].s < tr[x*2].rs + tr[x*2+1].ls) && 
    (tr[x*2].rs + tr[x*2+1].ls == tr[x*2+1].s)) 
        gx(tr[x],s_mid,tr[x*2],tr[x*2+1]);
    return;
}
struct dzpd getsum(int x)
{
    if (tr[x].l >= t1 && tr[x].r <= t2) return tr[x];
    if (tr[x].l == tr[x].r) return tr[x];
    if (tr[x*2].r >= t2) return (getsum(x*2));
    if (tr[x*2+1].l <= t1) return (getsum(x*2+1));
    
    

    t35 = getsum(x*2);
    t37 = getsum(x*2+1);
    t36.sum = t35.sum + t37.sum;
    t36.ls = t36.rs = t36.s = (-1 * 'e' * 'g' * 'g' * 'y');
    //ls:
    if (t36.ls < t35.ls) gx(t36,ls_l,t35,t37);
    if (t36.ls < t35.sum + t37.ls) gx(t36,ls_r,t35,t37);
    if (t35.ls == t35.sum + t37.ls) gx(t36,ls_l,t35,t37);
    //rs:
    if (t36.rs < t37.rs) gx(t36,rs_r,t35,t37);
    if (t36.rs < t37.sum + t35.rs) gx(t36,rs_l,t35,t37);
    if (t37.rs == t37.sum + t35.rs) gx(t36,rs_l,t35,t37);
    //s:
    if (t36.s < t35.s) gx(t36,s_l,t35,t37);
    if (t36.s < t35.rs + t37.ls) gx(t36,s_mid,t35,t37);
    if (t36.s < t37.s) gx(t36,s_r,t35,t37);
    if ((t35.s == t35.rs + t37.ls) && (t35.rs + t37.ls == t37.s)) gx(t36,s_l,t35,t37);
    else if ((t35.s < t35.rs + t37.ls) && (t35.rs + t37.ls == t37.s))
        gx(t36,s_mid,t35,t37);

    return t36;
}

//#define ls_l 'l' //以ls = ls_l求得ls
//#define ls_r 'L' //以ls = sum_l + ls_r求得ls
//#define rs_r 'r' //以rs = rs_r求得rs
//#define rs_l 'R' //以rs = sum_r + rs_l求得rs
//#define s_l 's' //以s = s_l求得s
//#define s_r 'S' //以s = s_r求得s
//#define s_mid 'm' //以s = ls_r + rs_l求得s
void gx(struct dzpd &x, char mode_cyy, struct dzpd l, struct dzpd r)
{
    switch(mode_cyy)
    {
        case ls_l:
            x.ls = l.ls;
            x.lsr = l.lsr;
            return;
        case ls_r:
            x.ls = l.sum + r.ls;
            x.lsr = r.lsr;
            return;
        case rs_r:
            x.rs = r.rs;
            x.rsl = r.rsl;
            return;
        case rs_l:
            x.rs = r.sum + l.rs;
            x.rsl = l.rsl;
            return;
        case s_l :
            x.s = l.s;
            x.sl = l.sl;
            x.sr = l.sr;
            return;
        case s_r :
            x.s = r.s;
            x.sl = r.sl;
            x.sr = r.sr;
            return;
        case s_mid :
            x.s = l.rs + r.ls;
            x.sl = l.rsl;
            x.sr = r.lsr;
            return;
    }return;
}
2024/6/22 15:26
加载中...