S
o
u
r
c
e
:
Source:
Source:151 - ZOJ Monthly, March 2018
P
r
o
b
l
e
m
:
Problem:
Problem:
- 1 l r: Change $(a_l, a_{l+1}, \dots, a_r) $to $(a_l^3, a_{l+1}^3, \dots, a_r^3)$;
- 2 l r: Query the value of $(\displaystyle\sum_{i=l}^r a_i)$ modulo 99971.
C o d e : Code: Code:
#include<bits/stdc++.h>
using namespace std;
#define lson o<<1
#define rson o<<1|1
const int MOD = 99971;
const int MAXN = 1e5+10;
struct Node {
int add, sum[50], t[50];
}b[MAXN<<2];
int ql, qr, a[MAXN], mark[50];
int sqr3(int x) { return 1LL*x*x%MOD*x%MOD; }
void build(int o, int L, int R) {
b[o].add = 0;
if(L == R) {
b[o].sum[0] = a[L];
b[o].t[0] = b[o].sum[0];
for(int i = 1; i < 48; i++) {
b[o].sum[i] = sqr3(b[o].sum[i-1]);
b[o].t[i] = b[o].sum[i];
}
return;
}
int M = (L+R)>>1;
build(lson, L, M);
build(rson, M+1, R);
for(int i = 0; i < 48; i++) {
b[o].sum[i] = (b[lson].sum[i]+b[rson].sum[i])%MOD;
}
}
void maintain(int o, int L, int R) {
for(int i = 0; i < 48; i++) {
if(R > L) b[o].sum[i] = (b[lson].sum[i]+b[rson].sum[i])%MOD;
else b[o].sum[i] = b[o].t[i];
}
int now = b[o].add;
now %= 48;
if(now) {
for(int i = 0; i < 48; i++) mark[i] = b[o].sum[i];
for(int i = 0; i < 48; i++) b[o].sum[i] = mark[(i+now)%48];
}
}
void pushdown(int o) {
b[lson].add += b[o].add;
b[rson].add += b[o].add;
b[o].add = 0;
}
void update(int o, int L, int R) {
if(ql<=L && qr>=R) {
b[o].add++;
}
else {
pushdown(o);
int M = (L+R)>>1;
if(ql <= M) update(lson, L, M); else maintain(lson, L, M);
if(qr > M) update(rson, M+1, R); else maintain(rson, M+1, R);
}
maintain(o, L, R);
}
int query(int o, int L, int R, int add) {
if(ql<=L && qr>=R) return b[o].sum[add%48];
else {
int M = (L+R)>>1;
int ret = 0;
if(ql <= M) ret += query(lson, L, M, add+b[o].add);
if(qr > M) ret += query(rson, M+1, R, add+b[o].add);
return ret%MOD;
}
}
int main() {
int X;
scanf("%d", &X);
while(X--) {
int n, q;
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
a[i] %= MOD;
}
build(1, 1, n);
while(q--) {
int op;
scanf("%d%d%d", &op, &ql, &qr);
if(op == 1) update(1, 1, n);
else printf("%d\n", query(1, 1, n, 0));
}
}
return 0;
}