Portal: http://www.lydsy.com/JudgeOnline/problem.php?id=1798
Note that the values maintained by the current node should be correct, and that the lazy tag is just a pass-through token, which should be updated immediately when the son's maintenance value is changed, and the current node's maintenance value should be updated immediately.
#include <cstdio>const int maxn = 100005;int N, mod, A[maxn], m, T1, T2, T3, opr;struct Node {int QL, Qr;long long s M, Mul, add;} TREE[MAXN << 2];inline void pushup (int p) {Tree[p].sm = (tree[p << 1].sm + tree[p << 1 | 1].sm)% mod;} inline void pushdown (int p) {tree[p << 1].mul = tree[p << 1].mul * Tree[p].mul% mod;tree[p << 1].add = (Tree[p << 1].add * tree[p].mul + tree[p].add)% mod;tree[p << 1].sm = (tree[p << 1].sm * Tree[p].mul + Tree[p].add * (tree[p << 1].qr-tree[p << 1].ql + 1))% mod;tree[p << 1 | 1].mul = tree[p << 1 | 1].mul * Tree[p].mul% mod;tree[p << 1 | 1].add = (tree[p << 1 | 1].add * tree[p].mul + tree[p].add)% Mod;tre E[p << 1 | 1].sm = (tree[p << 1 | 1].sm * Tree[p].mul + tree[p].add * (tree[p << 1 | 1].qr-tree[p < < 1 | 1].QL + 1))% Mod;tree[p].mul = 1;tree[p].add = 0;} void Make_tree (int p, int left, int. right) {TREE[P].QL = LEFT;TREE[P].QR= Right;tree[p].mul = 1;if (left = right) {Tree[p].sm = (long Long) (A[left]% mod); return;} int mid = (left + right) >> 1;make_tree (P << 1, left, mid), Make_tree (P << 1 | 1, mid + 1, right);p ushup ( p);} void Mull (int p, int left, int. right, int c) {if (tree[p].ql = = Left && TREE[P].QR = = right) {Tree[p].mul = Tree[p ].mul * (long Long) c% Mod;tree[p].add = Tree[p].add * (long Long) c% Mod;tree[p].sm = Tree[p].sm * (long Long) C% Mod;ret Urn;} Pushdown (P); int mid = (tree[p].ql + tree[p].qr) >> 1;if (right <= mid) {Mull (P << 1, left, right, c);} else if (Left > mid) {Mull (P << 1 | 1, left, right, c);} else {mull (P << 1, left, Mid, c); Mull (P << 1 | 1, mid + 1, right, c);} Pushup (P);} void addd (int p, int left, int. right, int c) {if (tree[p].ql = = && TREE[P].QR = = right) {Tree[p].add = (tree[ P].add + (Long long) c)% Mod;tree[p].sm = (Tree[p].sm + (long Long) c * (Long Long) (TREE[P].QR-TREE[P].QL + 1))% Mod;ret Urn;} Pushdown (p); int mid = (tree[p].ql + tree[p].qr) >> 1;if (right <= mid) {addd (P << 1, left, right, c);} else if (Left > mid) {addd (P << 1 | 1, left, right, c);} else {addd (P << 1, left, Mid, c); ADDD (P << 1 | 1, mid + 1, right, c);} Pushup (P);} int qry (int p, int left, int. right) {if (tree[p].ql = = Left && TREE[P].QR = = right) {return (int) Tree[p].sm;} Pushdown (P); int mid = (tree[p].ql + tree[p].qr) >> 1, rt;if (right <= mid) {RT = Qry (P << 1, left, right);} else if (Left > mid) {rt = Qry (P << 1 | 1, left, right);} else {RT = Qry (P << 1, left, mid), RT = (rt + qry (P << 1 | 1, mid + 1, right))% MoD;} Pushup (p); return RT;} int main (void) {//freopen ("In.txt", "R", stdin),//freopen ("OUT.txt", "w", stdout), scanf ("%d%d", &n, &mod); for ( int i = 1; I <= N; ++i) {scanf ("%d", A + i);} Make_tree (1, 1, N), scanf ("%d", &m), while (m--) {scanf ("%d%d%d", &opr, &t1, &t2), if (OPR = = 1) {scanf ("%d", &T3); Mull (1, T1,T2, T3);} else if (OPR = = 2) {scanf ("%d", &t3), addd (1, T1, T2, T3);} else {printf ("%d\n", qry (1, T1, T2));}} return 0;}
_bzoj1798 [ahoi2009]seq Maintenance sequence Seq "segment Tree lazy Tag"