Cod sursa(job #3036516)

Utilizator NathanBBerintan Emanuel Natanael NathanB Data 24 martie 2023 15:08:51
Problema Arbori indexati binar Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("aib.in");
ofstream fout("aib.out");

using VI = vector<int>;

int n,m,x,c;
VI v;

void Update(int poz,int val);
int Query(int poz);
int Show(int sum);

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    fin>>n>>m;
    v = VI(n+1);
    for(int i=1;i<=n;i++)
    {
        fin>>x;
        Update(i,x);
    }
    for(int i=1;i<=m;i++)
    {
        fin>>c;
        if(c==0)
        {
            int poz, val;
            fin>>poz>>val;
            Update(poz,val);
        }
        if(c==1)
        {
            int st,dr;
            fin>>st>>dr;
            fout<<Query(dr)-Query(st-1)<<'\n';
        }
        if(c==2)
        {
            int k;
            fin>>k;
            fout<<Show(k)<<'\n';
        }
    }
}

void Update(int poz,int val)
{
    for(int i=poz;i<=n;i += i&-i)
        v[i] += val;
}

int Query(int poz)
{
    int rez = 0;
    for(int i=poz;i>=1;i-=i&-i)
        rez += v[i];
    return rez;
}

int Show(int sum)
{
   int st = 1,dr = n,k,pos=n+1;
   k = n;
   int S  = Query(k);
   if(S==sum) pos = n;
   while(k)
   {
       k = (st+dr)>>1;
       S = Query(k);
       if(S>sum)
       {
           if(dr > k) dr = k;
           k-=1;
       }
       else if(S==sum) pos = min(pos,k), dr = k, k--;
       else
       {
           if(st<k) st = k;
           k+=1;
       }
       if(k <= st) break;
       if(k >= dr) break;
   }
   if(pos == n+1) return -1;
   return pos;
}