Cod sursa(job #1557583)

Utilizator DrumeaVDrumea Vasile DrumeaV Data 27 decembrie 2015 20:24:56
Problema SequenceQuery Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.74 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

typedef long long ll;

const int MX = 400006;
const ll If = 1LL * MX * MX;

struct node
{
    ll best,mn,mx;
};

int n,m,x,y;
ll sol,min_val;
ll sum[MX];
node t[MX];

void build_tree(int idx,int left,int right)
{
    if (left == right)
    {
        t[idx].mx = sum[left];
        t[idx].mn = sum[left - 1];
        t[idx].best = sum[left] - sum[left - 1];
        return;
    }

    int middle = (left + right) / 2;

    build_tree(2 * idx,left,middle);
    build_tree(2 * idx + 1,middle + 1,right);

    t[idx].mx = max(t[2 * idx].mx,t[2 * idx + 1].mx);
    t[idx].mn = min(t[2 * idx].mn,t[2 * idx + 1].mn);
    t[idx].best = max(max(t[2 * idx].best,t[2 * idx + 1].best),t[2 * idx + 1].mx - t[2 * idx].mn);
}

void query(int idx,int left,int right)
{
    if (x <= left && right <= y)
    {
        sol = max(sol,t[idx].best);

        if (min_val < If)
           sol = max(sol,t[idx].mx - min_val);

        min_val = min(min_val,t[idx].mn);
        return;
    }

    int middle = (left + right) / 2;

    if (x <= middle)
       query(2 * idx,left,middle);

    if (middle < y)
       query(2 * idx + 1,middle + 1,right);
}

int main()
{
    freopen("sequencequery.in","r",stdin);
    freopen("sequencequery.out","w",stdout);

     scanf("%d %d",&n,&m);

     for (int i = 1;i <= n;i++)
     {
         int x;

         scanf("%d",&x);
         sum[i] = x + sum[i - 1];
     }

     build_tree(1,1,n);

     for (int i = 1;i <= m;i++)
     {
         sol = -If;
         min_val = If;

         scanf("%d %d",&x,&y);
         query(1,1,n);

         printf("%lld\n",sol);
     }

  return 0;
}