区间修改板子1
只有一种操作,即在区间内每个数的加上k
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
const int maxn = 200000;
struct MyStruct {
ll sum, lazy;
}tree[maxn << 2];
ll n, m;
ll a[maxn];
void pushup(ll rt) {
tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
}
void build(ll l, ll r, ll rt) {
if (l == r) {
//scanf("%lld", &tree[rt].sum);
tree[rt].sum = a[l];
return;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
pushup(rt);
}
void ferr(ll add, ll l, ll r, ll rt) {
tree[rt].lazy += add;
tree[rt].sum += add * (r - l + 1);
}
void pushdown(ll l, ll r, ll rt) {
ll m = (l + r) >> 1;
ferr(tree[rt].lazy, lson);
ferr(tree[rt].lazy, rson);
tree[rt].lazy = 0;
}
void update(ll add,ll L,ll R,ll l,ll r,ll rt) {
if (L <= l && r <= R) {
ferr(add, l, r, rt);
return;
}
pushdown(l, r, rt);
ll m = (l + r) >> 1;
if (L <= m) update(add, L, R, lson);
if (R > m) update(add, L, R, rson);
pushup(rt);
}
ll query(ll L, ll R, ll l, ll r, ll rt) {
ll res = 0;
if (L <= l && r <= R) {
return tree[rt].sum;
}
ll m = (l + r) >> 1;
pushdown(l, r, rt);
if (L <= m) res += query(L, R, lson);
if (R > m) res += query(L, R, rson);
return res;
}
int main() {
int x, y, c, k;
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%lld",&a[i]);
}
build(1, n, 1);
for (int i = 1; i <= m; i++) {
scanf("%d", &c);
if (c == 1) {
scanf("%d%d%d", &x, &y, &k);
update(k, x, y, 1, n, 1);
}
else {
scanf("%d%d", &x, &y);
printf("%lld\n", query(x, y, 1, n, 1));
}
}
return 0;
}
区间修改板子2 有两种操作,在区间内同时加一个数与同时乘一个数
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lc rt<<1
#define rc rt<<1|1
struct MyStruct{
ll sum, add,mul;
}tree[maxn<<2];
ll n, k, a[maxn];
int p;
//void pushup(ll rt) {
// tree[rt].sum = tree[lc].sum + tree[rc].sum;
// tree[rt].sum %= p;
//}
void build(ll l, ll r, ll rt) {
tree[rt].add = 0;
tree[rt].mul = 1;
if (l == r) {
tree[rt].sum = a[l];
}
else {
ll m = (l + r) >> 1;
build(lson);
build(rson);
tree[rt].sum = tree[lc].sum + tree[rc].sum;
}
tree[rt].sum %= p;
return;
}
void pushdown(ll l, ll r, ll rt) {
ll m = (l + r) >> 1;
tree[rt*2].sum=(tree[rt*2].sum*tree[rt].mul+tree[rt].add*(m-l+1))%p;
tree[rt*2+1].sum=(tree[rt*2+1].sum*tree[rt].mul+tree[rt].add*(r-m))%p;
//很好维护的lazytag
tree[rt*2].mul=(tree[rt*2].mul*tree[rt].mul)%p;
tree[rt*2+1].mul=(tree[rt*2+1].mul*tree[rt].mul)%p;
tree[rt*2].add=(tree[rt*2].add*tree[rt].mul+tree[rt].add)%p;
tree[rt*2+1].add=(tree[rt*2+1].add*tree[rt].mul+tree[rt].add)%p;
tree[rt].mul=1;
tree[rt].add=0;
}
void ud1(ll mul, int L, int R, int l, int r, int rt){
//假如本区间和给出的区间没有交集
if(R<l || r<L){
return ;
}
//假如给出的区间包含本区间
if(L<=l && r<=R){
tree[rt].sum = (tree[rt].sum*mul) % p;
tree[rt].mul = (tree[rt].mul*mul) % p;
tree[rt].add = (tree[rt].add*mul) % p;
return ;
}
//假如给出的区间和本区间有交集,但是也有不交叉的部分
//先传递lazytag
pushdown(l, r, rt);
int m = (l + r) >> 1;
ud1(mul, L, R, lson);
ud1(mul, L, R, rson);
tree[rt].sum = (tree[rt * 2].sum + tree[rt * 2 + 1].sum) % p;
return ;
}
void ud2(ll add,ll L,ll R,ll l,ll r,ll rt){
if(R<l || r<L){
return ;
}
if(L<=l && r<=R){
tree[rt].add=(tree[rt].add+add)%p;
tree[rt].sum=(tree[rt].sum+add*(r-l+1))%p;
return ;
}
pushdown(l, r, rt);
ll m = (l + r) >> 1;
ud2(add, L, R, lson);
ud2(add, L, R, rson);
tree[rt].sum = (tree[rt * 2].sum + tree[rt * 2 + 1].sum) % p;
return ;
}
ll query(ll L, ll R, ll l, ll r, ll rt) {
if (L > r|| R < l) return 0;
if (L <= l && r <= R) {
return tree[rt].sum;
}
pushdown(l, r, rt);
ll res = 0, m = (l + r) >> 1;
return (query(L, R, lson) + query(L, R, rson)) % p;
}
int main(){
ios::sync_with_stdio(false);
cin >> n >> k >> p;
for (int i = 1; i <= n; i++) cin >> a[i];
build(1, n, 1);
while (k--) {
ll x, y, z, k;
cin >> z;
if (z == 1) {
cin >> x >> y >> k;
ud1(k, x, y, 1, n, 1);
}
else if (z == 2) {
cin >> x >> y >> k;
ud2(k, x, y, 1, n, 1);
}
else {
cin >> x >> y;
cout << query(x, y, 1, n, 1) << endl;
}
}
return 0;
}