Cod sursa(job #600265)

Utilizator cont_de_testeCont Teste cont_de_teste Data 30 iunie 2011 22:54:37
Problema SequenceQuery Scor 0
Compilator fpc Status done
Runda Arhiva de probleme Marime 3.41 kb
const   fin = 'sequencequery.in'; fout = 'sequencequery.out';

type    buffer = array[0..1 shl 17] of char;
        arbore = array[0..1 shl 18] of int64;
        vector = array[0..100000] of int64;

var     bufin, bufout : buffer;
        arb, first, last : arbore;
        sum : vector;
        r : int64;
        finish ,x ,y : longword;

function max( a, b, c : int64 ) : int64;
begin
        if (b > a) then a := b;
        if (c > a) then a := c;
        max := a;
end;

procedure getmax( nod : longword );
var     st, dr, amb ,gmax : int64;
begin
        st := arb[nod * 2];
        dr := arb[nod * 2 + 1];
        amb := st + dr + sum[first[nod * 2 + 1] - 1] - sum[last[nod * 2]];
        gmax := max( st, dr, amb );
        if (gmax = amb) then
        begin
                arb[nod] := amb;
                first[nod] := first[nod * 2];
                last[nod] := last[nod * 2 + 1];
        end else
        if (gmax = dr) then
        begin
                arb[nod] := dr;
                first[nod] := first[nod * 2 + 1];
                last[nod] := last[nod * 2 + 1];
        end else
        begin
                arb[nod] := st;
                first[nod] := first[nod * 2];
                last[nod] := last[nod * 2];
        end;
end;

procedure construct( nod, st, dr : longword );
var     mij : longword;
begin
        if (st = dr) then
        begin
                x := x + 1;
                arb[nod] := sum[st] - sum[st - 1];
                first[nod] := st;
                last[nod] := st;
        end else
        begin
                mij := (st + dr) div 2;
                construct( nod * 2, st, mij );
                construct( nod * 2 + 1, mij + 1, dr );
                getmax( nod );
        end;
end;

procedure getsol( nod : longword );
var     gmax, amb : int64;
begin
        if (finish = 0) then
        begin
                r := arb[nod];
                finish := last[nod];
        end else
        begin
                amb := r + arb[nod] + sum[first[nod] - 1] - sum[finish];
                gmax := max( r, arb[nod], amb );
                if (gmax = amb) then
                begin
                        r := amb;
                        finish := last[nod];
                end else
                if (gmax = arb[nod]) then
                begin
                        r := arb[nod];
                        finish := last[nod];
                end;
        end;
end;

procedure querry( nod, st, dr : longword );
var     mij : longword;
begin
        if (x <= st) and (dr <= y) then
        begin
                getsol( nod );
                exit();
        end;
        mij := (st + dr) div 2;
        if (x <= mij) then querry( nod * 2, st, mij );
        if (mij < y) then querry( nod * 2 + 1, mij + 1, dr );
end;

procedure main();
var     n, m, i : longword;
begin
        assign( input, fin ); reset( input );
        assign( output, fout ); rewrite( output );
        settextbuf( input, bufin );
        settextbuf( output, bufout );
        readln( n, m );
        for i := 1 to n do read( sum[i] );
        for i := 2 to n do sum[i] := sum[i] + sum[i - 1];

        construct( 1, 1, n );
        for i := 1 to m do
        begin
                read( x, y );
                finish := 0;
                querry( 1, 1, n );
                write( r , #10 );
        end;
end;

begin
        main();
end.