单点操作
//元素
struct node {
int l, r, sum;
} tr[maxn<<2]; //节点类型
//建树
void pushup(int m) { //向上更新
tr[m].sum=tr[m<<1].sum+tr[m<<1|1].sum;//一个节点的sum等于左节点的sum加右节点的sum
}
void build(int m, int l, int r) { //建树
tr[m].l=l; //最左
tr[m].r=r; //最右
if(l==r) { //只有一个点l==r
scanf("%d", &tr[m].sum);
return;
} //直接结束
int mid=(l+r)>>1;//求中间值
build(m<<1, l, mid);//左半边 m*2
build(m<<1|1, mid+1, r);//右半边 m*2+1
pushup(m);//向上更新
}
//单点更新
void updata(int m, int inx, int val) {
if(tr[m].l==inx&&tr[m].r==inx) { //如果找到那个值,直接更新
tr[m].sum+=val;
return;
}
int mid=(tr[m].l+tr[m].r)>>1;//求中间值
if(inx<=mid) //如果要找的值小于中间值,更新左半边
updata(m<<1, inx, val);
else
updata(m<<1|1, inx, val);//更新右半边
pushup(m);//向上更新
}
//查询
int query(int m, int l, int r) {//查询l到r
if(tr[m].l==l&&tr[m].r==r) {//如果找到那个区域,输出和(可以换)
return tr[m].sum;
}
int mid=(tr[m].l+tr[m].r)>>1;//求中间值
int temp;
if(r<=mid)//若中间值在要找区域的右边
temp=query(m<<1, l ,r);//查询左半部分
else if(l>mid)
temp=query(m<<1|1, l, r);
else//若mid 在所要找到范围里
temp=query(m<<1, l, mid)+query(m<<1|1, mid+1, r);//查询(l,mid)和(mid,r)
return temp;
}
版权声明:本文为red_red_red原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。