Cod sursa(job #781053)

Utilizator bratualexBratu Alexandru bratualex Data 23 august 2012 00:54:38
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 5.03 kb
#include <fstream>

using namespace std;
ifstream fin ("aib.in");
ofstream fout ("aib.out");

void modificare ( int , int );
//int doila ( int );
//int nrdoi (int );
int intunux (int );
int v[100009],i,j,k,n,x,m,p,vl,a,b,s,gata,ok,cnta,cntb;
int main()
{
    fin>>n>>m;
    for(i=1;i<=n;i++)
    {
        fin>>x;
        //aux[i]=aux[i-1]+x;
        modificare(i,x);
    }
    for (i=1;i<=m;i++)
    {
        fin>>x;
        switch ( x )
        {
            case 0:
                fin>>p>>vl;
                modificare (p,vl);
            break;
            case 1:
                //err++;

                fin>>a>>b;
                //if (err==498)
                //{
                //    fout<<"\n operatia este 1 :a si b :"<<a<<" "<<b<<"\n";
                //}
                if (a==1)
                    fout<<intunux(b)<<"\n";
                else
                    fout<<intunux(b)-intunux(a-1)<<"\n";
            break;
            case 2:
                fin>>x;
                //err++;
                //if (err==498)
                //{
                //    fout<<"\noperatia este 2 :x: "<<x<<"\n";
                //}
                /*
                gata=0;
                j=1;
                while (j<=n &&!gata)
                {
                    if(intunux(j)==x)
                        gata=1;
                    else
                        j++;
                }
                if (gata)
                    fout<<j<<"\n";
                else
                    fout<<"-1\n";
            */

            /*
                ok=0;
                cnta=1;
                cntb=2;
                while (!ok&&cnta<=n)
                {
                    if (cntb>=n)
                    {
                        cntb=n;
                        ok=1;
                    }
                    if (v[cnta]<=x&&v[cntb]>=x)
                        ok=1;
                    else
                    {
                        if (!ok)
                        {
                            cnta=cnta*2;
                            cntb=cntb*2;
                        }
                    }

                }
                if (cnta<=n)
                {
                    a=cnta;
                    b=cntb;
                    do
                    {
                        k=intunux ((a+b)/2);
                        if ( k<x )
                            a=(a+b)/2+1;
                    else
                        if (k>x)
                            b=(a+b)/2;
                    }
                    while (k!=x&&a<b);
                    k=intunux ((a+b)/2);
                    if (k==x)
                        fout<<(a+b)/2<<"\n";
                    else
                        fout<<"-1\n";
                }
                else
                {
                    fout<<"-1\n";

                }



*/
                ok=0;
                cnta=1;
                cntb=2;
                while (!ok&&cntb<=n)
                {
                    if(v[cnta]<=x&&v[cntb]>=x)
                        ok=1;
                    else
                    {
                        cnta=cnta*2;
                        cntb=cntb*2;
                    }

                }
                if(ok)
                {


                    a=cnta;
                    b=cntb;
                    do
                    {
                        k=intunux ((a+b)/2);
                        if ( k<x )
                            a=(a+b)/2+1;
                    else
                        if (k>x)
                            b=(a+b)/2;
                    }
                    while (k!=x&&a<b);

                    if (a==b)
                        k=intunux (b);
                    if (k==x)
                        fout<<(a+b)/2<<"\n";
                    else
                        fout<<"-1\n";
                }
                else
                {
                    a=cnta;
                    b=n;
                    do
                    {
                        k=intunux ((a+b)/2);
                        if ( k<x )
                            a=(a+b)/2+1;
                        else
                            if (k>x)
                                b=(a+b)/2;
                    }
                    while (k!=x&&a<b);
                    if (a==b)
                        k=intunux (a);
                    if (k==x)
                        fout<<(a+b)/2<<"\n";
                    else
                        fout<<"-1\n";
                }

            break;

        }

    }
    fin.close();
    fout.close();
    return 0;
}


void modificare (int poz , int val )
{
    while (poz<=n)
    {
        v[poz]+=val;
        poz+=poz^(poz&(poz-1));
    }
}



int intunux (int x )
{
    s=0;
    //fout<<"apelat pt "<<x;
    while (x>=1)
    {
        s+=v[x];
        x-=x^(x&(x-1));
    }
    //fout<<"afisat "<<s<<endl;
    return s;
}