区间更新,区间求和:
#include
using namespace std;
#define ll long long
#define lefs l, m, rt << 1
#define rigs m+1, r, rt << 1 | 1
#define lef rt << 1
#define rig rt << 1 | 1
#define mid (l + r) >> 1;
#define abb int l, int r, int rt
const int N = 1e5 + 7;
int n, m;
ll sum[N << 2], lazy[N << 2];
void pushup(int rt)
{
sum[rt] = sum[lef] + sum[rig];
}
void pushdown(abb)
{
if(lazy[rt])
{
lazy[lef] += lazy[rt];
lazy[rig] += lazy[rt];
int m = mid;
sum[lef] += (m - l + 1) * lazy[rt];
sum[rig] += (r - m) * lazy[rt];
lazy[rt] = 0;
}
}
void build(abb)
{
if(l == r)
{
scanf("%lld",&sum[rt]);
return;
}
int m = mid;
build(lefs); build(rigs);
pushup(rt);
}
void update(int L, int R, ll val, abb)
{
if(l >= L && r <= R)
{
lazy[rt] += val;
sum[rt] += (r - l + 1) * val;
return ;
}
pushdown(l, r, rt);
int m = mid;
if(m >= L) update(L, R, val, lefs);
if(m < R) update(L, R, val, rigs);
pushup(rt);
}
ll query(int L, int R, abb)
{
if(l >= L && r <= R)
return sum[rt];
pushdown(l, r, rt);
int m = mid; ll ans = 0;
if(m >= L) ans += query(L, R, lefs);
if(m < R) ans += query(L, R, rigs);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
build(1, n, 1);
int op, x, y; ll val;
while(m--)
{
scanf("%d",&op);
if(op == 1)
{
scanf("%d%d%lld",&x, &y, &val);
update(x, y, val, 1, n, 1);
}
else
{
scanf("%d%d",&x, &y);
cout << query(x, y, 1, n, 1) << endl;
}
}
}
单点更新/查询,区间更新/查询 :
#include
#include
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid (l+r)>>1
#define abb int l,int r,int rt
const int N = 1e5 + 7;
ll lazy[N<<2];
ll sum[N<<2];
inline void pushup(int rt)//更新父亲节点
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
inline void pushdown(abb) //标记下传
{
if(lazy[rt])
{
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
int m = mid;
sum[rt<<1] += (m-l+1) * lazy[rt];
sum[rt<<1|1] += (r-m) * lazy[rt];
lazy[rt] = 0;
}
}
inline void build(abb)
{
lazy[rt] = 0;
if(l == r)
{
scanf("%lld", &sum[rt]);
return ;
}
int m = mid;
build(lson);
build(rson);
pushup(rt);
}
inline void update(int L, int R, int c, abb)
{
if(L <= l && R >= r)
{
lazy[rt] += c;
sum[rt] += (r-l+1) * c;
return ;
}
pushdown(l, r, rt);
int m = mid;
if(L <= m) update(L, R, c, lson);
if(R > m) update(L, R, c, rson);
pushup(rt);
}
inline ll query(int L, int R, abb)
{
if(L <= l && R >= r)
return sum[rt];
pushdown(l, r, rt);
int m = mid;
ll ret = 0;
if(L <= m) ret += query(L, R, lson);
if(R > m) ret += query(L, R, rson);
return ret;
}
inline void update_point(int p, int c, abb)
{
if(l == r)
{
sum[rt] += c;
return ;
}
pushdown(l, r, rt);
int m = mid;
if(p <= m) update_point(p, c, lson);
else update_point(p, c, rson);
pushup(rt);
}
inline ll query_point(int p, abb)
{
if(l == r)
return sum[rt];
pushdown(l, r, rt);
int m = mid;
if(p <= m) query_point(p, lson);
else query_point(p, rson);
}
int main()
{
int m,n;
scanf("%d%d",&n, &m);
build(1, n, 1);
while(m--)
{
int a, b, c, p, op;
scanf("%d",&op);
if(op == 1) //单点更新
{
scanf("%d%d", &p, &c);
update_point(p, c, 1, n, 1);
}
if(op == 2) //单点查询
{
scanf("%d", &p);
printf("%lld\n",query_point(p, 1, n, 1));
}
if(op == 3) //区间更改
{
scanf("%d%d%d", &a, &b, &c);
update(a,b,c,1,n,1);
}
if(op == 4) //区间查询
{
scanf("%d%d", &a, &b);
printf("%lld\n",query(a, b, 1, n, 1));
}
}
return 0;
}