Pagini recente » Rotatie lexicografic minima | Statistici Ruxandra Hristache (hristacheruxi) | Istoria paginii runda/cni_preoji_2 | Autentificare | Cod sursa (job #2803742)
#include <assert.h>
#include <stdio.h>
#define MAXN 100000
#define LEASTSIG(x) (1 << (__builtin_ctz(x)))
int n;
int v[MAXN + 1];
int aib[MAXN + 1];
void
update (int poz, int val) {
int i;
for (i = poz; i <= n; i += LEASTSIG(i))
aib[i] += val;
}
int
compute (int node) {
int ret = 0;
int i;
for (i = node; i > 0; i -= LEASTSIG(i))
ret += aib[i];
return ret;
}
int
binSearch (int sum) {
int bg = 0;
int i;
for (i = 1 << 24; i; i >>= 1)
if (bg + i <= n && compute(bg + i) < sum)
bg += i;
if ((++ bg) <= n && compute(bg) == sum)
return bg;
return -1;
}
int main () {
int m;
int i;
assert(freopen("aib.in", "r", stdin));
assert(freopen("aib.out", "w", stdout));
assert(scanf("%d %d", &n, &m) == 2);
for (i = 0; i != n; ++ i) {
assert(scanf("%d", &v[i]) == 1);
update(i + 1, v[i]);
}
for (i = 0; i != m; ++ i) {
int tip, a, b;
assert(scanf(" %d", &tip) == 1);
switch (tip) {
case 0:
assert(scanf(" %d %d", &a, &b) == 2);
update(a, b);
break;
case 1:
assert(scanf(" %d %d", &a, &b) == 2);
printf("%d\n", compute(b) - compute(a - 1));
break;
case 2:
assert(scanf(" %d", &a) == 1);
printf("%d\n", binSearch(a));
break;
default:
assert(0);
}
}
}