RT,在 oiwiki 自学线段树,想打线段树,结果给我打挂了 QAQ
代码如下:
#include<bits/stdc++.h>
const int N = 1e5;
struct tree{
int sum, add, mul;
}tr[4 * N + 5];
int n, q, m, a[N + 5];
void pushup(int x){tr[x].sum = (tr[x << 1].sum + tr[x << 1 | 1].sum) % m;}
void build(int l, int r, int x){
tr[x].add = 0; tr[x].mul = 1;
if(l == r){
tr[l].sum = a[l];
return;
}
int mid = l + r >> 1;
build(l, mid, x << 1);
build(mid + 1, r, x << 1 | 1);
pushup(x);
}
void pushdown(int s, int t, int x){
int mid = s + t >> 1;
tr[x << 1].sum = (tr[x << 1].sum * tr[x].mul + tr[x].add * (mid - s + 1)) % m;
tr[x << 1| 1].sum = (tr[x << 1 | 1].sum * tr[x].mul + tr[x].add * (t - mid)) % m;
if(s != mid) tr[x << 1].add = (tr[x << 1].add * tr[x].mul + tr[x].add) % m, tr[x << 1].mul = tr[x << 1].mul * tr[x].mul % m;
if(mid + 1 != t) tr[x << 1 | 1].add=(tr[x << 1 | 1].add * tr[x].mul + tr[x].add) % m, tr[x << 1 | 1].mul = tr[x << 1 | 1].mul * tr[x].mul % m;
tr[x].add = 0; tr[x].mul = 1;
}
void update1(int l, int r, int s, int t, int x, int c){
if(l <= s&&t <= r){
tr[x].sum = (tr[x].sum + c * (t - s + 1)) % m;
tr[x].add = (tr[x].add + c) % m;
return;
}
int mid = s + t >> 1;
pushdown(s, t, x);
if(l <= mid) update1(l, r, s, mid, x << 1, c);
if(r > mid) update1(l, r, mid + 1, t, x << 1 | 1, c);
pushup(x);
}
void update2(int l,int r,int s,int t,int x,int c){
if(l <= s&&t <= r){
tr[x].sum = tr[x].sum * c % m;
tr[x].add = tr[x].add * c % m;
tr[x].mul = tr[x].mul * c % m;
return;
}
int mid = s + t >> 1;
pushdown(s, t, x);
if(l <= mid) update2(l, r, s, mid, x << 1, c);
if(r > mid) update2(l, r, mid + 1, t, x << 1 | 1, c);
pushup(x);
}
int ask(int l, int r, int s, int t, int x){
if(l <= s&&t <= r) return tr[x].sum % m;
int mid = s + t >> 1;
pushdown(s, t, x);
int res = 0;
if(l <= mid) res = (res + ask(l, r, s, mid, x << 1)) % m;
if(r > mid) res = (res + ask(l, r, mid + 1, t, x << 1 | 1)) % m;
return res % m;
}
int main(){
scanf("%d%d%d", &n, &q, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(1, n, 1);
while(q--){
int cz, x, y; scanf("%d%d%d", &cz, &x, &y);
if(cz == 3) printf("%d\n", ask(x, y, 1, n, 1) % m);
else{
int k; scanf("%d", &k);
if(cz == 1) update1(x, y, 1, n, 1, k);
else update2(x, y, 1, n, 1, k);
}
}
}
样例没过,找了好久找不出错。救救本蒟蒻吧~
(好像要开 longlong,但先解决我样例没过的问题吧)