點選檢視程式碼
// 改build ,apply ,operator +
// 奇奇怪怪 但能用
struct Tag{
ll add = 0;
void apply(Tag &t){
add += t.add;
return ;
}
};
struct Info{
ll sum = 0;
void apply (Tag &t, int l, int r){
sum += t.add * (r - l + 1);
return ;
}
};
Info operator + (const Info &a,const Info &b) {
Info c;
c.sum = a.sum + b.sum;
return c;
}
struct Seg{
int n;
vector<Info>info;
vector<Tag>tag;
Seg(int n){
info.resize(4 * n + 4);
tag.resize(4 * n + 4);
this -> n = n;
}
void down(int p, int l, int r){
int m = (l + r) / 2;
info[2 * p].apply(tag[p], l, m);
info[2 * p + 1].apply(tag[p], m + 1, r);
tag[2 * p].apply(tag[p]);
tag[2 * p + 1].apply(tag[p]);
tag[p] = Tag();
}
void merge(int p){
info[p] = info[2 * p]+info[2 * p + 1];
}
void build(vector<int> & a){
auto build = [&](auto &&self, int p, int l, int r)->void{
if(l == r){
info[p].sum = a[l];
return ;
}
int m = (l + r) / 2;
self(self, 2 * p, l, m);
self(self, 2 * p + 1, m + 1, r);
merge(p);
};
build(build, 1, 1, n);
}
Info query(int p, int l, int r, int ql, int qr){
if(ql > r || qr < l)return Info();
if(ql <= l && qr >= r){
return info[p];
}
down(p, l, r);
merge(p);
int m = (l + r ) / 2;
return query(2 * p, l, m, ql, qr) + query(2 * p + 1, m + 1, r, ql, qr);
}
void modify(int p, int l, int r, int ql, int qr, int w){
if(ql > r || qr < l)return ;
if(ql <= l && qr >= r){
info[p].sum += (r - l + 1) * w;
tag[p].add += w;
return ;
}
int m = (l + r) / 2;
down(p, l, r);
modify(2 * p, l, m, ql, qr, w);
modify(2 * p + 1, m + 1, r, ql, qr, w);
merge(p);
}
};