UVALive - 3938:"Ray, Pass me the dishes!"

Posted white_hat_hacker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVALive - 3938:"Ray, Pass me the dishes!"相关的知识,希望对你有一定的参考价值。

优美的线段树

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#define MAXN 500000+10
#define ll long long
#define pii pair<int,int>
#define mp make_pair
using namespace std;
int a[MAXN];
int n,m;
struct Node{
    int pre_dat;
    ll pre_sum;
    int suf_dat;
    ll suf_sum;
    pii dat;
    ll sum;
    ll d;
    Node(int p1=0,ll p2=0,int p3=0,ll p4=0,pii p5=mp(0,0),ll p6=0,ll p7=0){
        pre_dat=p1,pre_sum=p2,suf_dat=p3,suf_sum=p4,dat=p5,sum=p6,d=p7;
    }
}data[MAXN<<2]; 
Node Merge(Node t1,Node t2){
    if(t1.dat==mp(0,0))return t2;
    if(t2.dat==mp(0,0))return t1;
    Node ret;
    ret.d=t1.d+t2.d;
    ret.pre_dat=t1.pre_dat,ret.pre_sum=t1.pre_sum;
    if(ret.pre_sum<t1.d+t2.pre_sum){
        ret.pre_dat=t2.pre_dat,ret.pre_sum=t1.d+t2.pre_sum;
    }
    ret.suf_dat=t2.suf_dat,ret.suf_sum=t2.suf_sum;
    if(ret.suf_sum<=t2.d+t1.suf_sum){
        ret.suf_dat=t1.suf_dat,ret.suf_sum=t2.d+t1.suf_sum;
    }
    ret.dat=t1.dat,ret.sum=t1.sum;
    if(ret.sum<t2.sum){
        ret.dat=t2.dat,ret.sum=t2.sum;
    }
    if(ret.sum<(t1.suf_sum+t2.pre_sum)||ret.sum==(t1.suf_sum+t2.pre_sum)&&ret.dat>mp(t1.suf_dat,t2.pre_dat)){
        ret.dat=mp(t1.suf_dat,t2.pre_dat),
        ret.sum=(t1.suf_sum+t2.pre_sum);
    }
    return ret;
}
void build(int k,int L,int R){
    if(L+1==R){
        data[k].pre_dat=data[k].suf_dat=L;
        data[k].dat=mp(L,L);
        data[k].d=data[k].pre_sum=data[k].suf_sum=data[k].sum=a[L];
        return;
    }
    build(k<<1,L,(L+R)>>1);
    build(k<<1|1,(L+R)>>1,R);
    data[k]=Merge(data[k<<1],data[k<<1|1]);
}
Node query(int a,int b,int k,int L,int R){
    if(b<=L||R<=a){
        return Node(0,0,0,0,mp(0,0),0,0);
    }    
    else if(a<=L&&R<=b){
        return data[k];
    }
    else{
        int mid=((L+R)>>1);
        Node lc=query(a,b,k<<1,L,mid);
        Node rc=query(a,b,k<<1|1,mid,R);
        return Merge(lc,rc);
    }
}
void solve(){
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    build(1,1,n+1);
    while(m--){
        int x,y;
        scanf("%d%d",&x,&y);
        Node ans=query(x,y+1,1,1,n+1);
        printf("%d %d\n",ans.dat.first,ans.dat.second);
    }
}    
int main()
{
//    freopen("data.in","r",stdin);
//    freopen("my.out","w",stdout);
    int T=0;
    while(~scanf("%d%d",&n,&m)){
        printf("Case %d:\n",++T);
        solve();
    }
    return 0;
}    

 

以上是关于UVALive - 3938:"Ray, Pass me the dishes!"的主要内容,如果未能解决你的问题,请参考以下文章

Ray, Pass me the dishes!

UVALive - 3938 分治,线段树,求动态最大连续和

UVALive - 3211 (2-SAT + 二分)

训练指南 UVALive - 3713 (2-SAT)

训练指南 UVALive - 3415(最大点独立集)

训练指南 UVALive - 3126(DAG最小路径覆盖)