码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1798 [Ahoi2009]Seq 维护序列seq

时间:2015-05-25 22:06:08      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

原题链接: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

 

 

bzoj 1798 [Ahoi2009]Seq 维护序列seq

标签:

原文地址:http://www.cnblogs.com/GadyPu/p/4528938.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!