1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
| #include <iostream>
#include <cstdio>
using namespace std;
const int INF = 1<<30;
typedef long long LL;
int getint() {
int r = 0, k = 1; char c = getchar();
for (; '0' > c || c > '9'; c = getchar()) if (c == '-') k = -1;
for (; '0' <= c && c <= '9'; c = getchar()) r = r * 10 - '0' + c;
return r * k;
}
const int N=100005;
int n, m;
LL p;
LL mul[N*4], plu[N*4], tree[N*4], a[N], siz[N*4];
void pu(int now) {
tree[now]=(tree[now<<1]+tree[now<<1|1])%p;
}
void build(int now, int l, int r) {
mul[now]=1;
plu[now]=0;
if (l==r) {
tree[now]=a[l];
siz[now]=1;
return;
}
int mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
pu(now);
siz[now] = siz[now<<1] + siz[now<<1|1];
return;
}
void pd(int now) {
if(mul[now]==1&&plu[now]==0) return;
mul[now<<1]=(mul[now<<1]*mul[now])%p;
mul[now<<1|1]=(mul[now<<1|1]*mul[now])%p;
plu[now<<1]=(plu[now<<1]*mul[now]+plu[now])%p;
plu[now<<1|1]=(plu[now<<1|1]*mul[now]+plu[now])%p;
tree[now<<1]=(tree[now<<1]*mul[now]+plu[now]*siz[now<<1])%p;
tree[now<<1|1]=(tree[now<<1|1]*mul[now]+plu[now]*siz[now<<1|1])%p;
mul[now]=1;plu[now]=0;
}
void chan(int now, int l, int r, int ll, int rr, LL mulval, LL pluval) {
if (ll<=l&&r<=rr) {
if (l != r) {
mul[now]=(mul[now]*mulval)%p;
plu[now]=(plu[now]*mulval+pluval)%p;
}
tree[now]=(tree[now]*mulval+siz[now]*pluval)%p;
return;
}
int mid = (l+r)>>1;
pd(now);
if(ll<=mid)chan(now<<1,l,mid,ll,rr,mulval,pluval);
if(rr>mid)chan(now<<1|1,mid+1,r,ll,rr,mulval,pluval);
pu(now);
}
LL ask(int now, int l, int r, int ll, int rr) {
if (ll <= l && r <= rr) return tree[now] % p;
int mid = (l+r)>>1;
LL ret = 0;
pd(now);
if(ll<=mid)ret=ask(now<<1,l,mid,ll,rr)%p;
if(rr>mid)ret=(ret+ask(now<<1|1,mid+1,r,ll,rr))%p;
return ret;
}
int main() {
n=getint(); p=getint();
for (int i = 1; i <= n; ++i) a[i]=(getint())%p;
build(1,1,n);
int op, x, y, z;
for (m=getint();m;--m){
op=getint();
if (op == 1) {
x=getint();y=getint();z=getint();
chan(1,1,n,x,y,z%p,0);
continue;
}
if (op == 2) {
x=getint();y=getint();z=getint();
chan(1,1,n,x,y,1,z%p);
continue;
}
if (op == 3) {
x=getint();y=getint();
printf("%lld\n", ask(1,1,n,x,y));
continue;
}
}
}
|