bzoj 1798 [Ahoi2009]Seq 维护序列seq

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 

线段树区间更新:

 1. 区间同同时加上一个数 2. 区间同时乘以一个数

 1 #include<algorithm>

 2 #include<iostream>

 3 #include<cstdlib>

 4 #include<cstdio>

 5 #define lc root<<1

 6 #define rc root<<1|1

 7 typedef unsigned long long ull;

 8 const int Max_N = 100010;

 9 int Mod;

10 struct Node {

11     ull sum, add, mul;

12 };

13 struct SegTree {

14     Node seg[Max_N << 2];

15     inline void push_up(int root) {

16         seg[root].sum = (seg[lc].sum + seg[rc].sum) % Mod;

17     }

18     inline void built(int root, int l, int r) {

19         seg[root].add = 0, seg[root].mul = 1;

20         if (l == r) {

21             scanf("%lld", &seg[root].sum);

22             seg[root].sum %= Mod;

23             return;

24         }

25         int mid = (l + r) >> 1;

26         built(lc, l, mid);

27         built(rc, mid + 1, r);

28         push_up(root);

29     }

30     inline void push_down(int root, int len) {

31         if (seg[root].add != 0 || seg[root].mul != 1) {

32             ull &_add = seg[root].add, &_mul = seg[root].mul;

33             seg[lc].sum = (seg[lc].sum * _mul + (len - (len >> 1)) * _add) % Mod;

34             seg[lc].mul = (seg[lc].mul * _mul) % Mod;

35             seg[lc].add = (seg[lc].add * _mul + _add) % Mod;

36             seg[rc].sum = (seg[rc].sum * _mul + (len >> 1) * _add) % Mod;

37             seg[rc].mul = (seg[rc].mul * _mul) % Mod;

38             seg[rc].add = (seg[rc].add * _mul + _add) % Mod;

39             _add = 0, _mul = 1;

40         }

41     }

42     inline void update(int root, int l, int r, int x, int y, ull val, ull mul) {

43         if (x > r || y < l) return;

44         if (x <= l && y >= r) {

45             seg[root].add = (seg[root].add * mul + val) % Mod;

46             seg[root].mul = (seg[root].mul * mul) % Mod;

47             seg[root].sum = (seg[root].sum * mul + val * (r - l + 1)) % Mod;

48             return;

49         }

50         push_down(root, r - l + 1);

51         int mid = (l + r) >> 1;

52         update(lc, l, mid, x, y, val, mul);

53         update(rc, mid + 1, r, x, y, val, mul);

54         push_up(root);

55     }

56     inline ull query(int root, int l, int r, int x, int y) {

57         if (x > r || y < l) return 0;

58         if (x <= l && y >= r) {

59             return seg[root].sum;

60         }

61         push_down(root, r - l + 1);

62         ull ret = 0;

63         int mid = (l + r) >> 1;

64         ret += query(lc, l, mid, x, y);

65         ret += query(rc, mid + 1, r, x, y);

66         return ret %= Mod;

67     }

68 }seg;

69 int main() {

70 #ifdef LOCAL

71     freopen("in.txt", "r", stdin);

72     freopen("out.txt", "w+", stdout);

73 #endif

74     int n, m, a, b, c, d;

75     while (~scanf("%d %d", &n, &Mod)) {

76         seg.built(1, 1, n);

77         scanf("%d", &m);

78         while (m--) {

79             scanf("%d", &a);

80             if (1 == a) {

81                 scanf("%d %d %d", &b, &c, &d);

82                 seg.update(1, 1, n, b, c, 0, d);

83             } else if (2 == a) {

84                 scanf("%d %d %d", &b, &c, &d);

85                 seg.update(1, 1, n, b, c, d, 1);

86             } else {

87                 scanf("%d %d", &b, &c);

88                 printf("%lld\n", seg.query(1, 1, n, b, c));

89             }

90         }

91     }

92     return 0;

93 }
View Code

 

 

你可能感兴趣的:(ZOJ)