#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#define CHECK_INDEX(idx, min, max, ret) if(idx < min || idx > max) { \
croak("Index not in range [" IVdf "," IVdf "]", (IV)(min), (IV)(max)); \
return ret; \
}
typedef struct {
IV n;
IV* t;
} bit;
bit* bit_create(IV len) {
if(len < 1){
croak("Length less than 1");
return 0;
}
len++;
bit *ret;
Newx(ret, 1, bit);
ret->n = len;
Newxz(ret->t, len, IV);
return ret;
}
void bit_free(bit *b) {
Safefree(b->t);
Safefree(b);
}
IV bit_query(bit *b, IV idx) {
CHECK_INDEX(idx, 0, b->n - 1, 0);
IV ret = 0;
while(idx)
ret += b->t[idx], idx -= idx & -idx;
return ret;
}
void bit_update(bit *b, IV idx, IV value) {
CHECK_INDEX(idx, 0, b->n - 1, );
while(idx < b->n)
b->t[idx] += value, idx += idx & -idx;
}
void bit_clear(bit *b) {
Zero(b->t, b->n, IV);
}
typedef struct {
IV n, m;
IV* t;
} bit2d;
bit2d* bit2d_create(IV n, IV m) {
if(n < 1 || m < 1){
croak("A dimension is less than 1");
return 0;
}
n++, m++;
bit2d *ret;
Newx(ret, 1, bit2d);
ret->n = n;
ret->m = m;
Newxz(ret->t, n * m, IV);
return ret;
}
void bit2d_free(bit2d *b) {
Safefree(b->t);
Safefree(b);
}
IV bit2d_query(bit2d *b, IV i1, IV i2) {
CHECK_INDEX(i1, 1, b->n - 1, 0);
CHECK_INDEX(i2, 1, b->m - 1, 0);
if(i1 > b->n || i1 < 1) {
croak("Index 1 not in range [1," IVdf "]", b->n);
return 0;
}
if(i2 > b->m || i2 < 1) {
croak("Index 2 not in range [1," IVdf "]", b->m);
return 0;
}
IV ret = 0, i2c = i2;
while(i1) {
i2 = i2c;
while(i2)
ret += b->t[i1 * b->m + i2], i2 -= i2 & -i2;
i1 -= i1 & -i1;
}
return ret;
}
void bit2d_update(bit2d *b, IV i1, IV i2, IV value) {
CHECK_INDEX(i1, 1, b->n - 1, );
CHECK_INDEX(i2, 1, b->m - 1, );
IV i2c = i2;
while(i1 < b->n) {
i2 = i2c;
while(i2 < b->m)
b->t[i1 * b->m + i2] += value, i2 += i2 & -i2;
i1 += i1 & -i1;
}
}
void bit2d_clear(bit2d *b) {
Zero(b->t, b->n * b->m, IV);
}
typedef bit *Algorithm__BIT__XS;
typedef bit2d *Algorithm__BIT2D__XS;
MODULE = Algorithm::BIT::XS PACKAGE = Algorithm::BIT::XS PREFIX = bit_
PROTOTYPES: ENABLE
Algorithm::BIT::XS bit_create(IV len);
void bit_free(Algorithm::BIT::XS b);
ALIAS:
DESTROY = 1
IV bit_query(Algorithm::BIT::XS b, IV idx);
void bit_update(Algorithm::BIT::XS b, IV idx, IV value);
void bit_clear(Algorithm::BIT::XS b);
MODULE = Algorithm::BIT::XS PACKAGE = Algorithm::BIT2D::XS PREFIX = bit2d_
PROTOTYPES: ENABLE
Algorithm::BIT2D::XS bit2d_create(IV n, IV m);
void bit2d_free(Algorithm::BIT2D::XS b);
ALIAS:
DESTROY = 1
IV bit2d_query(Algorithm::BIT2D::XS b, IV i1, IV i2);
void bit2d_update(Algorithm::BIT2D::XS b, IV i1, IV i2, IV value);
void bit2d_clear(Algorithm::BIT2D::XS b);