TODO
template
template<typename T=int,int N=maxn>
struct sgt_range {
T tr[N*4+5];
T flag[N*4+5]; //flag 里的内容与题目有关,灵活设定
inline int lp(int p){return p<<1;}
inline int rp(int p){return (p<<1)|1;}
inline int mid(int l,int r){return (l+r)>>1;}
inline void pushup(int p){ //向上合并
tr[p] = tr[lp(p)] + tr[rp(p)];
}
inline void pushdown(int p,int m){ //向下压标记
if( flag[p] ){ //当前点有flag
flag[lp(p)] = flag[rp(p)] = flag[p];
tr[lp(p)] = flag[p]*(m-(m>>1)); //成段替换需要这样写
tr[rp(p)] = flag[p]*(m>>1);
flag[p] = 0;
}
}
void build(int l,int r,int p){ //建立
if( l == r ) {
scanf("%d",&tr[p]);
return;
}
int m = mid(l,r);
build(l,m,lp(p));
build(m+1,r,rp(p));
pushup(p);
}
// 区间更新
void update(int L,int R,T v,int l,int r,int p){
if(L <= l && r <= R) {
flag[p] = v;
tr[p] = (r-l+1)*v;
return;
}
pushdown(p,r-l+1); //路过
int m = mid(l,r);
if( L<=m)
update(L,R,v,l,m,lp(p));
if( R>=m+1)
update(L,R,v,m+1,r,rp(p));
pushup(p);
}
//区间查询
T query(int L,int R,int l,int r,int p){
if( L <=l && r<=R ) {
return tr[p];
}
pushdown(p, r-l+1);
int m = mid(l,r);
T ret = 0;
if( L <= m ) ret+=query(L,R,l,m,lp(p));
if( R >=m+1) ret+=query(L,R,m+1,r,rp(p));
//pushup(p);
return ret;
}
};
sgt_range<> sgt;