bit.cpp (6)
BIT có hàm lower_bound tìm số i nhỏ nhất sao cho get(1,i)>=X
Bài toán
Với một dãy số, thực hiện các truy vấn:
u X Y : tăng phần tử thứ X lên Y đơn vị
g X Y : tính tổng các phần tử từ X đến Y
f X : tìm số i nhỏ nhất sao cho get(1,i) >= X
Độ phức tạp
update: O(logn)
get: O(logn)
find: O(logn)
Code này của Nguyễn Tiến Trung Kiên
#include <stdio.h>
#include <stdlib.h>
#define long long long
#define SetLength(a, n, type) a = (type*) calloc(n, sizeof (type))
struct indexed_tree {
int n, logn;
long * T;
void clear(int N){
n=1, logn=0;
while (n<N) { n*=2; logn++; }
SetLength(T, n+1, long);
}
void update(int pos, int value){
for (int i=pos; i<=n; i+=i&-i)
T[i]+=value;
}
long get(int pos){
long r=0;
for (int i=pos; i>=1; i-=i&-i)
r += T[i];
return r;
}
long get(int ll, int rr){
return get(rr)-get(ll-1);
}
int lower_bound(int node, int level, long value){
for (int i=level-1; i>=0; i--)
if (T[node-(1<<i)]>=value)
return lower_bound(node-(1<<i), i, value);
else value-=T[i];
return node;
}
int lower_bound(long value){
if (value>T[n]) return 0;
else return lower_bound(n, logn, value);
}
};
int n, m;
indexed_tree tr;
main(){
char c; int i, x, y;
scanf("%d%d", &n, &m);
tr.clear(n);
for (i=1; i<=m; i++){
scanf(" %c", &c);
if (c=='u' || c=='g') scanf("%d%d", &x, &y);
else if (c=='f') scanf("%d", &x);
if (c=='u') tr.update(x, y);
if (c=='g') printf("%lld\n", tr.get(x, y));
if (c=='f') printf("%d\n", tr.lower_bound(x));
}
}
Nhận xét