参考:https://www.cnblogs.com/shadowland/p/5870339.html,http://www.cnblogs.com/shadowland/p/5870354.html
!!主程序arr读取从1开始!!
#define MAXN 100000+5
#define iLEF i<<1
#define iRIG i<<1|1
struct BNode
{
int l,r,v;
int set,add;
}BTree[MAXN<<2];
int arr[MAXN]; //每个节点对应的值
void Build(int l,int r,int i)
{
BTree[i].l = l;
BTree[i].r = r;
BTree[i].set = 0;
BTree[i].add = 0;
if(l==r){
BTree[i].v = arr[l];
return;
}
int m = (l+r)>>1;
Build(l,m,iLEF);
Build(m+1,r,iRIG);
BTree[i].v = BTree[iLEF].v + BTree[iRIG].v;
}
//set
void Pushdown_set(int i)
{
if(BTree[i].set){
BTree[iLEF].set = BTree[i].set;
BTree[iRIG].set = BTree[i].set;
int m = (BTree[i].l+BTree[i].r)>>1;
BTree[iLEF].v = BTree[i].set*(m-BTree[i].l+1);
BTree[iRIG].v = BTree[i].set*(BTree[i].r-m);
BTree[i].set = 0;
}
}
void Update_set(int s,int e,int i,int v)
{
if(s<=BTree[i].l&&e>=BTree[i].r){
BTree[i].set = v;
BTree[i].v = (BTree[i].r-BTree[i].l+1)*v;
return;
}
Pushdown_set(i);
int m = (BTree[i].l+BTree[i].r)>>1;
if(e<=m) Update_set(s,e,iLEF,v);
else if(s>m) Update_set(s,e,iRIG,v);
else{
Update_set(s,e,iLEF,v);
Update_set(s,e,iRIG,v);
}
BTree[i].v = BTree[iLEF].v+BTree[iRIG].v;
}
int Query_set(int s,int e,int i)
{
if(s<=BTree[i].l&&e>=BTree[i].r) return BTree[i].v;
Pushdown_set(i);
int m = (BTree[i].l+BTree[i].r)>>1;
if(e<=m) return Query_set(s,e,iLEF);
else if(s>m) return Query_set(s,e,iRIG);
else{
return Query_set(s,e,iLEF)+Query_set(s,e,iRIG);
}
}
//add
void Pushdown_add(int len,int i) // len = BTree[i].r-BTree[i].l+1
{
if(BTree[i].add){
BTree[iLEF].add = BTree[i].add;
BTree[iRIG].add = BTree[i].add;
BTree[iLEF].v+=(len-len>>1)*BTree[i].add;
BTree[iRIG].v+=(len>>1)*BTree[i].add;
BTree[i].add = 0;
}
}
void Update_add(int s,int e,int i,int v)
{
if(s<=BTree[i].l&&e>=BTree[i].r){
BTree[i].add += v;
BTree[i].v += (BTree[i].r-BTree[i].l+1)*v;
return;
}
Pushdown_add(BTree[i].r-BTree[i].l+1,i);
int m = (BTree[i].r+BTree[i].l)>>1;
if(e<=m){
Update_add(s,e,iLEF,v);
}
else if(s>m){
Update_add(s,e,iRIG,v);
}
else{
Update_add(s,e,iLEF,v);
Update_add(s,e,iRIG,v);
}
BTree[i].v = BTree[iLEF].v+BTree[iRIG].v;
}
int Query_add(int s,int e,int i)
{
if(s<=BTree[i].l&&e>=BTree[i].r){
return BTree[i].v;
}
Pushdown_add(BTree[i].r-BTree[i].l+1,i);
int m = (BTree[i].r+BTree[i].l)>>1;
if(e<=m){
return Query_add(s,e,iLEF);
}
else if(s>m){
return Query_add(s,e,iRIG);
}
else{
return Query_add(s,e,iLEF)+Query_add(s,e,iRIG);
}
}