sicily 1136 山海经

来源:互联网 发布:软件数据线 v6.6 编辑:程序博客网 时间:2024/05/02 04:33

#include <iostream>

#include <stdio.h>

using namespace std;


const int N = 100000;
#define lchild(p) (((p)<<1)+1)
#define rchild(p) (((p)+1)<<1)


struct node {
int left, right;
int ms, start, end;
int lms, lend;
int rms, rstart;
int sum;
};
struct Ret {
int ms, start, end;
int lms, lend;
int rms, rstart;
int sum;
};
node tree[N*4];
int value[N+10];


void build( int p, int left, int right )
{
tree[p].left = left;
tree[p].right = right;
if ( left == right )
{
tree[p].sum = tree[p].lms = tree[p].rms = tree[p].ms = value[left];
tree[p].start = tree[p].end = tree[p].lend = tree[p].rstart = left;
}
else{
int mid = (left+right)>>1;
int tmp;
build( lchild(p), left, mid );
build( rchild(p), mid+1, right );


//
tree[p].sum = tree[ lchild(p) ].sum + tree[ rchild(p) ].sum;


//ms start end
tmp = tree[ lchild(p) ].rms + tree[ rchild(p) ].lms;
if ( tree[ lchild(p) ].ms > tmp 
|| ( tree[ lchild(p) ].ms == tmp && tree[ lchild(p) ].start <= tree[ lchild(p) ].rstart ) )
{
tree[p].ms = tree[ lchild(p) ].ms;
tree[p].start = tree[ lchild(p) ].start;
tree[p].end = tree[ lchild(p) ].end;
}
else {
tree[p].ms = tmp;
tree[p].start = tree[ lchild(p) ].rstart;
tree[p].end = tree[ rchild(p) ].lend;
}
if ( tree[ rchild(p) ].ms > tree[p].ms )
{
tree[p].ms = tree[ rchild(p) ].ms;
tree[p].start = tree[ rchild(p) ].start;
tree[p].end = tree[ rchild(p) ].end;
}


// lms lend
tmp = tree[ lchild(p) ].sum + tree[ rchild(p) ].lms;
if ( tree[ lchild(p) ].lms >= tmp )
{
tree[p].lms = tree[ lchild(p) ].lms;
tree[p].lend = tree[ lchild(p) ].lend;
}
else {
tree[p].lms = tmp;
tree[p].lend = tree[ rchild(p) ].lend;
}


//rms rstart
tmp = tree[ lchild(p) ].rms + tree[ rchild(p) ].sum;
if ( tmp >= tree[ rchild(p) ].rms )
{
tree[p].rms = tmp;
tree[p].rstart = tree[ lchild(p) ].rstart;
}
else {
tree[p].rms = tree[ rchild(p) ].rms;
tree[p].rstart = tree[ rchild(p) ].rstart;
}
}
}


void find( int p, int left, int right, Ret *pret )
{
if ( ( left <= tree[p].start && right >= tree[p].end ) )
{
pret->ms = tree[p].ms;
pret->start = tree[p].start;
pret->end = tree[p].end;
pret->lms = tree[p].lms;
pret->lend = tree[p].lend;
pret->rms  = tree[p].rms;
pret->rstart = tree[p].rstart;
pret->sum = tree[p].sum;
return;
}


int mid = ( tree[p].left + tree[p].right )>>1;
if ( right <= mid )
find( lchild(p), left, right, pret );
else if ( left > mid )
find( rchild(p), left, right, pret );
else{
Ret lret, rret;
int tmp;
find( lchild(p), left, mid, &lret );
find( rchild(p), mid+1, right, &rret );


//
pret->sum = lret.sum + rret.sum;
//ms start end
tmp = lret.rms + rret.lms;
if ( lret.ms > tmp 
|| ( lret.ms == tmp && lret.start <= lret.rstart ) )
{
pret->ms = lret.ms;
pret->start = lret.start;
pret->end = lret.end;
}
else {
pret->ms = tmp;
pret->start = lret.rstart;
pret->end = rret.lend;
}
if ( rret.ms > pret->ms )
{
pret->ms = rret.ms;
pret->start = rret.start;
pret->end = rret.end;
}
// lms lend
tmp = lret.sum + rret.lms;
if ( lret.lms >= tmp )
{
pret->lms = lret.lms;
pret->lend = lret.lend;
}
else {
pret->lms = tmp;
pret->lend = rret.lend;
}
//rms rstart
tmp = lret.rms + rret.sum;
if ( tmp >= rret.rms )
{
pret->rms = tmp;
pret->rstart = lret.rstart;
}
else {
pret->rms = rret.rms;
pret->rstart = rret.rstart;
}
}
}


int main()
{
int n, m, i, a, b;
Ret ret;
while ( scanf("%d%d", &n, &m ) != EOF )
{
for ( i = 1; i <= n; ++ i )
scanf("%d", &value[i] );
build( 0, 1, n );
for ( i = 0; i < m; ++ i )
{
scanf("%d%d", &a, &b );
find( 0, a, b, &ret );
printf("%d %d %d\n", ret.start, ret.end, ret.ms );
}
}
return 0;
}
原创粉丝点击