Cod sursa(job #2093272)

Utilizator gundorfMoldovan George gundorf Data 23 decembrie 2017 12:28:46
Problema Sortare prin comparare Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <iostream>
#include <fstream>
#define Nmax 100010
#include <cmath>
using namespace std;
ifstream fin("datorii.in");
ofstream fout("datorii.out");
int n,suma[Nmax],m;
int arb[300000];

void Citire ()
{ int i;
    fin>>n>>m;
    for (i=1; i<=n; i++)
        fin>>suma[i];

}
int Creare_arb (int l,int r,int nod)
{
    if (r==l) arb[nod]=suma[l]; //daca sunt intr o frunza suma pe intervalul ala e chiar elementul din vector
    else
    {
        int middle=(l+r)/2;
        Creare_arb ( l,middle,2*nod ) ; //impart intervalul in 2
        Creare_arb ( middle+1 ,r , 2*nod+1 ) ;
        arb[nod]=arb[2*nod]+arb[2*nod+1]; //altfel, e suma dintre cele 2 intervale de sub el
    }
}

int cautare_binara (int nod,int st,int dr,int x) // caut frunza (adica pozitia in vectorul arb ) corespunzatoare pozitiei x din vectorul inital
{

    while (st<=dr)
    { int middle=(st+dr)/2;
        if (st==dr&&st==x) return nod;

        if (middle<x) { nod = nod*2 + 1 ; st = middle + 1 ; }
        else { nod = nod*2 ; dr = middle ; }
    }

}


void update (int poz)
{
  arb[poz/2]=arb[poz/2*2]+arb[poz/2*2+1];

  if (poz!=1) update (poz/2);

}

int query (int nod,int l,int r,int st,int dr)
{ int v1=0,v2=0;
    if (l>=st && r<=dr)
        return arb[nod];

    if (l>dr||r<st) return 0;

    int middle=l+(r-l)/2;
    v1=query (2*nod,l,middle,st,dr);
    v2=query (2*nod+1,middle+1,r,st,dr);

    return v1+v2;

}


int main()
{int i,cod,y,x;
    Citire();
    Creare_arb(1,n,1);
   for (i=1;i<=m;i++)
    {
        fin>>cod>>x>>y;
        if (cod==1) fout<<query(1,1,n,x,y)<<"\n";
        if (cod==0)
        {
           // v[y]=z;
            int poz=cautare_binara(1,1,n,x);
            arb[poz]-=y;
            update(poz);
        }
    }


    return 0;
}