是复杂度错了还是常数问题?
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define MAXN 100001
#define MAXM 321
int uread(){
int x(0);
char ch;
while ((ch = getchar()) < 48);
do{
x = (x << 1) + (x << 3) + (ch ^ 48);
}while ((ch = getchar()) > 47);
return x;
}
int n, m, mod, opt, l, r, k, len, tot;
int a[MAXN], bl[MAXN];
int L[MAXM], R[MAXM];
int sum[MAXM], add[MAXM], mul[MAXM];
void init(){
len = sqrt(n);
tot = (n-1)/len+1;
for (int i(1); i<=tot; ++i){
L[i] = R[i-1] + 1;
R[i] = i * len;
}
R[tot] = n;
for (int i(1); i<=tot; ++i){
for (int j(L[i]); j<=R[i]; ++j){
bl[j] = i;
sum[i] += a[j];
}
mul[i] = 1;
}
}
void push_up(int x){
sum[x] = 0;
for (int i(L[x]); i<=R[x]; ++i) sum[x] += a[i];
}
void push_down(int x){
for (int i(L[x]); i<=R[x]; ++i) a[i] = (a[i] * mul[x] + add[x]) % mod;
mul[x] = 1;
add[x] = 0;
}
void upd1(int l, int r, int c){
int p(bl[l]), q(bl[r]);
if (p == q){
push_down(p);
for (int i(l); i<=r; ++i) a[i] = (a[i] + c) % mod;
push_up(p);
return;
}
push_down(p);
for (int i(l); i<=R[p]; ++i) a[i] = (a[i] + c) % mod;
push_up(p);
for (int i(p+1); i<q; ++i){
add[i] = (add[i] + c) % mod;
sum[i] = (sum[i] + len * c) % mod;
}
push_down(q);
for (int i(L[q]); i<=r; ++i) a[i] = (a[i] + c) % mod;
push_up(q);
}
void upd2(int l, int r, int c){
int p(bl[l]), q(bl[r]);
if (p == q){
push_down(p);
for (int i(l); i<=r; ++i) a[i] = (a[i] * c) % mod;
push_up(p);
return;
}
push_down(p);
for (int i(l); i<=R[p]; ++i) a[i] = (a[i] * c) % mod;
push_up(p);
for (int i(p+1); i<q; ++i){
add[i] = (add[i] * c) % mod;
mul[i] = (mul[i] * c) % mod;
sum[i] = (sum[i] * c) % mod;
}
push_down(q);
for (int i(L[q]); i<=r; ++i) a[i] = (a[i] * c) % mod;
push_up(q);
}
int query(int l, int r){
int p(bl[l]), q(bl[r]), ans(0);
if (p == q){
push_down(p);
for (int i(l); i<=r; ++i) ans = (ans + a[i]) % mod;
return ans;
}
push_down(p);
for (int i(l); i<=R[p]; ++i) ans = (ans + a[i]) % mod;
for (int i(p+1); i<q; ++i) ans = (ans + sum[i]) % mod;
push_down(q);
for (int i(L[q]); i<=r; ++i) ans = (ans + a[i]) % mod;
return ans;
}
signed main(){
n = uread();
m = uread();
mod = uread();
for (int i(1); i<=n; ++i) a[i] = uread();
init();
while (m--){
opt = uread();
l = uread();
r = uread();
if (opt == 2){
k = uread();
upd1(l, r, k);
}else if (opt == 1){
k = uread();
upd2(l, r, k);
}else printf("%lld\n", query(l, r));
}
return 0;
}