This is probably the case again. (2 <= z <= 6) then it is obviously a multi-line segment tree. For different z, they are maintained separately. But each time we can see that the subscript should be I-l + 1, so it is not fixed. However, in s [I] [j], j is related to the I model. Therefore, for different z, multiple line segment trees are maintained, make statistics on each mode. The approximate line segment tree maintains the first position of a range, which is % I = j. It is similar to HDU 4288 in push_up and query. [Cpp] # include <iostream> # include <cstdio> # include <cstring> # define mem (a, B) memset (a, B, sizeof ()) # define N 100005 # define lson step <1 # define rson step <1 | 1 # define LL long using namespace std; struct Seg_tree {int left, right; LL sum [7] [10];} L [N <2]; int s [7] [10]; int n, m, a [N]; void Init () {for (int I = 2; I <= 6; I ++) {for (int j = 0; j <2*(I-1 ); j ++) if (j = 0) s [I] [j] = 2; else if (j <= I) s [I] [j] = j; else if (j> I) s [I] [j] = 2 * I-j;} void push_up (int step) {for (int I = 2; I <= 6; I ++) for (int j = 0; j <2 * (I-1); j ++) {int d = L [lson]. right-L [lson]. left + 1; L [step]. sum [I] [j] = (L [lson]. sum [I] [j] + L [rson]. sum [I] [(j + d) % (2 * (I-1)]) ;}} void bulid (int step, int l, int r) {L [step]. left = l; L [step]. right = r; if (l = r) {for (int I = 2; I <= 6; I ++) for (int j = 0; j <2 * (I-1); j ++) L [step]. sum [I] [j] = (LL) s [I] [j] * a [l]; return;} int m = (l + r)> 1; bulid (lson, l, m); bulid (rson, m + 1, r); push_up (step);} LL query (int step, int l, int r, int z, int x) {if (L [step]. left = l & L [step]. right = r) {// mod z = x return L [step]. sum [z] [x];} int m = (L [step]. left + L [step]. right)> 1; if (r <= m) return query (lson, l, r, z, x); else if (l> m) return query (rson, l, r, z, x); else return query (lson, l, m, z, x) + query (rson, m + 1, r, z, (x + (m-l + 1) % (2 * (Z-1);} void update (int step, int pos, int val) {if (L [step]. left = pos & L [step]. right = pos) {// mod (2 * (I-1) = j for (int I = 2; I <= 6; I ++) for (int j = 0; j <2 * (I-1); j ++) L [step]. sum [I] [j] = (LL) val * s [I] [j]; return;} int m = (L [step]. left + L [step]. right)> 1; if (pos <= m) update (lson, pos, val); else update (rson, pos, val); push_up (step );} int main () {Init (); scanf ("% d", & n); for (int I = 1; I <= n; I ++) scanf ("% d", & a [I]); bulid (1, 1, n); scanf ("% d", & m); while (m --) {int k, l, r, z; scanf ("% d", & k); if (k = 1) {scanf ("% d ", & l, & z); update (1, l, z);} else {scanf ("% d", & l, & r, & z ); printf ("% I64d \ n", query (1, l, r, z, 1) ;}} return 0 ;} # include <iostream> # include <cstdio> # include <cstring> # define mem (a, B) memset (a, B, sizeof ()) # define N 100005 # define lson step <1 # define rson step <1 | 1 # define LL long using namespace std; struct Seg_tree {int left, right; LL sum [7] [10];} L [N <2]; int s [7] [10]; int n, m, a [N]; void Init () {for (int I = 2; I <= 6; I ++) {for (int j = 0; j <2*(I-1 ); j ++) if (j = 0) s [I] [j] = 2; else if (j <= I) s [I] [j] = j; else if (j> I) s [I] [j] = 2 * I-j;} void push_up (int step) {for (int I = 2; I <= 6; I ++) for (int j = 0; j <2 * (I-1); j ++) {int d = L [lson]. right-L [lson]. left + 1; L [step]. sum [I] [j] = (L [lson]. sum [I] [j] + L [rson]. sum [I] [(j + d) % (2 * (I-1)]) ;}} void bulid (int step, int l, int r) {L [step]. left = l; L [step]. right = r; if (l = r) {for (int I = 2; I <= 6; I ++) for (int j = 0; j <2 * (I-1); j ++) L [step]. sum [I] [j] = (LL) s [I] [j] * a [l]; return;} int m = (l + r)> 1; bulid (lson, l, m); bulid (rson, m + 1, r); push_up (step);} LL query (int step, int l, int r, int z, int x) {if (L [step]. left = l & L [step]. right = r) {// mod z = x return L [step]. sum [z] [x];} int m = (L [step]. left + L [step]. right)> 1; if (r <= m) return query (lson, l, r, z, x); else if (l> m) return query (rson, l, r, z, x); else return query (lson, l, m, z, x) + query (rson, m + 1, r, z, (x + (m-l + 1) % (2 * (Z-1);} void update (int step, int pos, int val) {if (L [step]. left = pos & L [step]. right = pos) {// mod (2 * (I-1) = j for (int I = 2; I <= 6; I ++) for (int j = 0; j <2 * (I-1); j ++) L [step]. sum [I] [j] = (LL) val * s [I] [j]; return;} int m = (L [step]. left + L [step]. right)> 1; if (pos <= m) update (lson, pos, val); else update (rson, pos, val); push_up (step );} int main () {Init (); scanf ("% d", & n); for (int I = 1; I <= n; I ++) scanf ("% d", & a [I]); bulid (1, 1, n); scanf ("% d", & m); while (m --) {int k, l, r, z; scanf ("% d", & k); if (k = 1) {scanf ("% d ", & l, & z); update (1, l, z);} else {scanf ("% d", & l, & r, & z ); printf ("% I64d \ n", query (1, l, r, z, 1) ;}} return 0 ;}