Cod sursa(job #2269529)

Utilizator razviii237Uzum Razvan razviii237 Data 26 octombrie 2018 09:26:47
Problema SequenceQuery Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.66 kb
#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

typedef long long lint;

const int maxn = 1e5+5, inf = 0x3f3f3f3f;

ifstream f("sequencequery.in");
ofstream g("sequencequery.out");

lint n, m, i, x, y;
lint v[maxn], sp[maxn];
lint k;

struct sq
{
    lint mx, mn, best;
}a[420];

void sqrtk()
{
    k = sqrt(n);
    lint i, j = 1, sum = 0;

    for(i = 1; i <= n; i ++) {
        sp[i] = sp[i-1] + v[i];
        if(i > (j * (n / k))) {
            ++j;
            a[j] = {-inf, inf, -inf};
            sum = 0;
            a[j].mn = sp[i-1];
        }

        sum += v[i];

        if(sum > a[j].best)
        { a[j].best = sum; }


        if(sum < 0)
            sum = 0;

        if(sp[i] > a[j].mx) {
            a[j].mx = sp[i];
        } if(sp[i] < a[j].mn) {
            a[j].mn = sp[i];
        }
    }
}

inline lint land(lint x) {
    return ((x - 1) / (n / k) + 1);
}

inline lint area(lint s) {
    return ((n / k) * (s - 1) + 1);
}

lint query(lint x, lint y)
{
    lint i, sum;
    lint fx, fy;
    fx = land(x);
    fy = land(y);

    if(fx == fy)
    {
        sum = 0;
        lint rez = -inf;
        for(i = x; i <= y; i ++)
        {
            sum += v[i];
            if(sum > rez) {
                rez = sum;
            }
            if(sum < 0) { sum = 0; }
        }
        return rez;
    }

    lint as = area(fx + 1) - 1, af = area(fy - 1) + (n / k);

    while(af > y) {
        af -= (n - k);
    }

    lint first = -inf, fm = inf, last = -inf, lm = -inf;

    sum = 0;
    fm = sp[x-1];
    for(i = x; i <= as; i ++)
    {
        sum += v[i];
        if(sum > first) {
            first = sum;
        }

        if(sum < 0) { sum = 0; }

        if(sp[i] < fm) { fm = sp[i]; }
    }

    sum = 0;

    for(i = af; i <= y; i ++) {
        sum += v[i];
        if(sum > last)
            { last = sum; }
        if(sum < 0) { sum = 0; }
        if(sp[i] > lm) { lm = sp[i]; }
    }



    lint mnn = fm, rez = -inf;

    if(first > rez) { rez = first; }

    for(i = fx + 1; i <= fy - 1; i ++)
    {

        if(a[i].mx - mnn > rez) { rez = a[i].mx - mnn; }

        if(a[i].mn < mnn) {mnn = a[i].mn; }

        if(a[i].best > rez) { rez = a[i].best; }

    }
    if(lm - mnn > rez) { rez = lm - mnn; }
    if(last > rez) { rez = last; }

    return rez;

}



int main()
{

    f >> n >> m;

    for(i = 1; i <= n; i ++) {
        f >> v[i];
    }

    sqrtk();

    while(m --)
    {
        f >> x >> y;
        g << query(x, y) << '\n';
    }

    f.close();
    g.close();
    return 0;
}