Pagini recente » Cod sursa (job #2726359) | Cod sursa (job #2833535) | Cod sursa (job #2005716) | Cod sursa (job #1962474) | Cod sursa (job #2093272)
#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;
}