Cod sursa(job #1149597)

Utilizator c0rn1Goran Cornel c0rn1 Data 22 martie 2014 02:16:13
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.9 kb
/**     Suma din intervalul [w, ww]
Arbori indexati binari, incepe de la 1.


c[i] = suma din [i-2^k+1, i]
k = poz cel mai nesimnificativ bit 1 din binar(i)
c: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

c1      0001, sum(1, 1)
c2      0010, sum(1, 2)
c3      0011, sum(3, 3)
c4      0100, sum(1, 4)
c5      0101, sum(5, 5)
c6      0110, sum(5, 6)
c7      0111, sum(7, 7)
c8      1000, sum(1, 8)
c9      1001, sum(9, 9)
c10     1010, sum(9, 10)
c11     1011, sum(11, 11)
c12     1100, sum(9, 12)
c13     1101, sum(13, 13)
c14     1110, sum(13, 14)
c15     1111, sum(15, 15)


(construire la inceput, vector c plin de 0)
acutalizare(poz, val)
_____________________
c[3] 0011 + 2^0 = 0100 -> c[4]  /// 0 = k-ul lui 0011
c[4] 0100 + 2^2 = 1000 -> c[8]  /// 2 = k-ul lui 0100
c[8] 1000 + 2^3 = 10000 -> 16 iesire

c[5] 0101 + 2^0 = 0110 c[6] + 2^1 = 1000 c[8] + 2^3 = 16 iese
c[4] 0100 + 2^2 = c[8] + 2^3 = 16 iese


int bit(int x)
{
    /// x =             ?????1000
    /// x-1 =           ?????0111
    /// x & (x-1) =     ?????0000
    /// (x&(x-1))^x =   000001000
    return ((x&(x-1))^x);
}

actualiz()
{
    while (poz<=n)
    {
        c[poz]+=val;
        poz+=bit(poz);
    }
}
____________________________________________

sum(st, dr) = sum(1,dr) - sum(1,st-1);
sum(1, 11) = ?
11 = 1011 - 2^k = 1010 = 10 => c[11] -> c[10]
10 = 1010 - 2^1 = 1000 = 8 => c[10] -> c[8]
8 = 1000 - 2^3 = 0 iesire.

=> sum(1, 11) = c[11] + c[10] + c[8];


suma(dr)
{
    int s=1;
    while(dr>0)
    {
        s+=c[dr];
        dr-=bit(dr);
    }
    return s;
}

*/

#include <iostream>
#include <stdio.h>

using namespace std;
int n, m, c[100010];

int bit(int p)
{
    return ((p&(p-1))^p);
}

void actualiz(int x, int poz)
{
    while (poz<=n)
    {
        c[poz]+=x;
        poz+=bit(poz);
    }
}

int suma(int dr)
{
    int s=0;
    while(dr>0)
    {
        s+=c[dr];
        dr-=bit(dr);
    }
    return s;
}

void cit()
{
    int x, p, tip;
    scanf("%d %d", &n, &m);
    for (int i=1; i<=n; i++)
    {
        scanf("%d", &x);
        actualiz(x, i);
    }
    for (int i=1; i<=m; i++)
    {
        scanf("%d", &tip);
        if (tip==0)
        {
            scanf("%d %d", &p, &x);
            actualiz(x, p);
        }
        else if (tip==1)
        {
            scanf("%d %d", &x, &p);
            int aux=suma(p);
            aux-=suma(x-1);
            printf("%d\n", aux);
        }
        else if (tip==2)
        {
            int s;
            scanf("%d", &x);
            for (int i=1; i<=n; i++)
            {
                s=suma(i);
                if (s==x)
                    printf("%d\n", i);
                else if (s>=x)
                    break;
            }
        }
    }
}

int main()
{
    freopen("aib.in", "r", stdin);
    freopen("aib.out", "w", stdout);
    cit();
    return 0;
}