这是洛谷线段树模板题绿标题,线段树好像没什么好总结的,主要看脑子
1 #include<iostream> 2 using namespace std; 3 #define int long long 4 const int N = 1e5 + 10, inf = 0x3f3f3f3f3f3f3f3f; 5 int n, q, m; 6 int f[4 * N], a[N], lazy1[4 * N], lazy2[4 * N]; 7 //lazy标记更新操作 8 void tag(int k, int l, int mid, int r) { 9 f[2 * k] = (lazy2[k] * f[2 * k] % m + ((mid - l + 1) * lazy1[k]) % m) % m; 10 f[2 * k + 1] = (lazy2[k] * f[2 * k + 1] % m + ((r - mid) * lazy1[k]) % m) % m; 11 lazy2[2 * k] = (lazy2[2 * k] * lazy2[k]) % m; 12 lazy2[2 * k + 1] = (lazy2[2 * k + 1] * lazy2[k]) % m; 13 lazy1[2 * k] = ((lazy1[2 * k] * lazy2[k]) % m + lazy1[k]) % m; 14 lazy1[2 * k + 1] = ((lazy1[2 * k + 1] * lazy2[k]) % m + lazy1[k]) % m; 15 lazy1[k] = 0; lazy2[k] = 1; 16 } 17 //建树 18 void build(int k, int l, int r) { 19 lazy2[k] = 1; lazy1[k] = 0; 20 if (l == r) { 21 f[k] = a[l] % m; 22 return; 23 } 24 int mid = (l + r) >> 1; 25 build(2 * k, l, mid); 26 build(2 * k + 1, mid + 1, r); 27 f[k] = (f[2 * k] + f[2 * k + 1]) % m; 28 } 29 //区间加法操作 30 void add(int k, int l, int r, int x, int y, int val) { 31 if (l >= x && r <= y) { 32 f[k] = (f[k] + ((r - l + 1) * val) % m) % m; 33 lazy1[k] = (lazy1[k] + val) % m; 34 return; 35 } 36 int mid = (l + r) >> 1; 37 tag(k, l, mid, r); 38 if (x <= mid)add(2 * k, l, mid, x, y, val); 39 if (y > mid)add(2 * k + 1, mid + 1, r, x, y, val); 40 f[k] = (f[2 * k] + f[2 * k + 1]) % m; 41 } 42 //区间乘法操作 43 void mul(int k, int l, int r, int x, int y, int val) { 44 if (l >= x && r <= y) { 45 f[k] = (f[k] * val) % m; 46 lazy2[k] = (lazy2[k] * val) % m; 47 lazy1[k] = (lazy1[k] * val) % m; 48 return; 49 } 50 int mid = (l + r) >> 1; 51 tag(k, l, mid, r); 52 if (x <= mid)mul(2 * k, l, mid, x, y, val); 53 if (y > mid)mul(2 * k + 1, mid + 1, r, x, y, val); 54 f[k] = (f[2 * k] + f[2 * k + 1]) % m; 55 } 56 //查询区间总和操作 57 int check(int k, int l, int r, int x, int y) { 58 if (l >= x && r <= y) return f[k]; 59 int mid = (l + r) >> 1; 60 tag(k, l, mid, r); 61 int ans1 = 0, ans2 = 0; 62 if (x <= mid)ans1 = check(2 * k, l, mid, x, y); 63 if (y > mid)ans2 = check(2 * k + 1, mid + 1, r, x, y); 64 return (ans1 % m + ans2 % m) % m; 65 } 66 void solve() { 67 cin >> n >> q >> m; 68 for (int i = 1; i <= n; i++)cin >> a[i]; 69 build(1, 1, n); 70 while (q--) { 71 int op; 72 cin >> op; 73 if (op == 2) { 74 int x, y, k; 75 cin >> x >> y >> k; 76 add(1, 1, n, x, y, k); 77 } 78 else if (op == 1) { 79 int x, y, k; 80 cin >> x >> y >> k; 81 mul(1, 1, n, x, y, k); 82 } 83 else if (op == 3) { 84 int x, y; 85 cin >> x >> y; 86 int res = check(1, 1, n, x, y); 87 cout << res % m << "\n"; 88 } 89 } 90 } 91 signed main() { 92 ios::sync_with_stdio(false); 93 cin.tie(0); 94 cout.tie(0); 95 int t = 1; 96 //cin >> t; 97 while (t--)solve(); 98 return 0; 99 }
那么多行,wa后调试真的会疯。。。
标签:lazy2,lazy1,int,线段,mid,void,op From: https://www.cnblogs.com/DLSQS-lkjh/p/17592110.html