Cod sursa(job #2756554)

Utilizator NeacsuMihaiNeacsu Mihai NeacsuMihai Data 1 iunie 2021 13:14:33
Problema SequenceQuery Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.8 kb
#include <iostream>
#include <fstream>

#define NMAX 100000

using namespace std;

ifstream fin ("sequencequery.in");
ofstream fout ("sequencequery.out");

struct element{
    long long maxIndSum; //max independent de unde se afla
    long long leftSum, rightSum;
    long long totSum;
};

int X, Y;
int v[NMAX + 1];
element tree[4 * NMAX + 1];

element rezultat(element A, element B, int dim1, int dim2){
    element rez;

    rez.maxIndSum = max(A.maxIndSum, B.maxIndSum);

    //if(A.rightSum > 0 && B.leftSum > 0){
        //cel din mijloc devine un candidat pt suma independenta
        rez.maxIndSum = max(rez.maxIndSum, A.rightSum + B.leftSum);

    rez.leftSum = max(A.leftSum, A.totSum + B.leftSum);
    rez.rightSum = max(B.rightSum, B.totSum + A.rightSum);

    rez.totSum = A.totSum + B.totSum;

    return rez;
}

void buildArbore(int node, int left, int right){
    if(left == right){
        tree[node].leftSum = v[left];
        tree[node].rightSum = v[left];

        tree[node].maxIndSum = v[left];
        tree[node].totSum = v[left];
        return;
    }

    int mid = left + (right - left) / 2;

    buildArbore(node * 2, left, mid);
    buildArbore(node * 2 + 1, mid + 1, right);

    tree[node] = rezultat(tree[node * 2], tree[node * 2 + 1], mid - left + 1, right - mid);
}

element query(int node, int left, int right){
    if(X <= left && right <= Y){
        return tree[node];
    }

    int mid = left + (right - left) / 2;

    element aux1, aux2;
    int OK1 = 0, OK2 = 0;
    if(X <= mid){
        //e relevant si fiul din stanga
        aux1 = query(node * 2, left, mid);
        OK1 = 1;
    }
    if(mid + 1 <= Y){
        //e relevant si fiul din dreapta
        aux2 = query(node * 2 + 1, mid + 1, right);
        OK2 = 1;
    }

    if(OK1 == 1 && OK2 == 1){
        return rezultat(aux1, aux2, mid - left + 1, right - mid); //daca le am pe ambele
    }
    else if(OK1 == 1){
        return aux1;
    }
    else {
        return aux2;
    }
}

int main()
{
    /*
    //testez functia rezultat();
    element A;
    A.leftSize = 3;
    A.rightSize = 3;
    A.maxIndSum = 30;
    A.leftSum = 30;
    A.rightSum = 30;

    element B;
    B.leftSize = 1;
    B.rightSize = 2;
    B.maxIndSum = 10;
    B.leftSum = 3;
    B.rightSum = 9;

    element AUB;
    AUB = rezultat(A, B, 3, 7);

    cout << AUB.leftSize << "\n" << AUB.rightSize << "\n" << AUB.maxIndSum << "\n" << AUB.leftSum << "\n" << AUB.rightSum;
    */



    int N, M;
    fin >> N >> M;

    for(int i = 1; i <= N; i++){
        fin >> v[i];
    }

    buildArbore(1, 1, N);


    for(int q = 1; q <= M; q++){
        fin >> X >> Y;

        element aux = query(1, 1, N);
        fout << aux.maxIndSum << "\n";
    }

    return 0;
}