posted on 2019-10-06 22:08:50
【模板】线段树 1
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; typedef long long lld; int n ,m; const int N = 1e5 + 5; lld sum[N << 2], tag[N << 2]; void pushup(int u) { sum[u] = sum[u << 1] + sum[u << 1 | 1]; } void build(int u, int l, int r) { if(l == r) { cin >> sum[u]; return; } int mid = l + r >> 1; build(u << 1, l, mid); build(u << 1 | 1, mid + 1, r); pushup(u); } void update(int u, int l, int r, int x) { tag[u] += x; sum[u] += (lld)x * (r - l + 1); } void pushdown(int u, int l, int r) { if(tag[u]) { int mid = l + r >> 1; update(u << 1, l, mid, tag[u]); update(u << 1 | 1, mid + 1, r, tag[u]); tag[u] = 0; } } void modify(int u, int ul, int ur, int ml, int mr, int x) { if(ml <= ul && mr >= ur) { update(u, ul, ur, x); return; } pushdown(u, ul, ur); int mid = ul + ur >> 1; if(ml <= mid) modify(u << 1, ul, mid, ml, mr, x); if(mid + 1 <= mr) modify(u << 1 | 1, mid + 1, ur, ml, mr, x); pushup(u); } lld query(int u, int ul, int ur, int ml, int mr) { if(ml <= ul && mr >= ur) { return sum[u]; } pushdown(u, ul, ur); int mid = ul + ur >> 1; lld s = 0; if(ml <= mid) s += query(u << 1, ul, mid, ml, mr); if(mr >= mid + 1) s += query(u << 1 | 1, mid + 1, ur, ml, mr); return s; } int main() { cin >> n >> m; build(1, 1, n); while(m--) { int ord, x, y, z; cin >> ord >> x >> y; if(ord == 1) { cin >> z; modify(1, 1, n, x, y, z); } else cout << query(1, 1, n, x, y) << endl; } return 0; }
【模板】树状数组 1
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; const int N = 5e5 + 5; int n, m, t[N]; typedef long long lld; int lowbit(int x) { return x & -x; } void modify(int i, lld x) { while(i <= n) { t[i] += x; i += lowbit(i); } } lld query(int i) { lld sum = 0; while(i) { sum += t[i]; i -= lowbit(i); } return sum; } int main() { cin >> n >> m; for(int i = 1; i <= n; i++) { int x; cin >> x; modify(i, x); } for(int i = 1; i <= m; i++) { int ord, x, y; cin >> ord >> x >> y; if(ord == 1) { modify(x, y); } else { cout << query(y) - query(x - 1) << endl; } } return 0; }
【模板】线段树 2
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; const int N = 1e5 + 1; typedef long long lld; int n, p, m; lld sum[N << 2], plutag[N << 2], multag[N << 2]; void pushup(int u) { sum[u] = sum[u << 1] + sum[u << 1 | 1]; sum[u] %= p; } void build(int u, int l, int r) { multag[u] = 1; if(l == r) { cin >> sum[u]; sum[u] %= p; return; } int mid = l + r >> 1; build(u << 1, l, mid); build(u << 1 | 1, mid + 1, r); pushup(u); } void pushdown(int u, int m) { if(multag[u] == 1 && plutag[u] == 0) return; sum[u << 1] = (sum[u << 1] * multag[u] + (m - (m >> 1)) * plutag[u]) % p; sum[u << 1 | 1] = (sum[u << 1 | 1] * multag[u] + (m >> 1) * plutag[u]) % p; multag[u << 1] = (multag[u << 1] * multag[u]) % p; multag[u << 1 | 1] = (multag[u << 1 | 1] * multag[u]) % p; plutag[u << 1] = (plutag[u << 1] * multag[u] + plutag[u]) % p; plutag[u << 1 | 1] = (plutag[u << 1 | 1] * multag[u] + plutag[u]) % p; multag[u] = 1; plutag[u] = 0; } void pludate(int u, int l, int r, lld x) { plutag[u] = (plutag[u] + x) % p; sum[u] = (sum[u] + x * (r - l + 1)) % p; } void muldate(int u, int l, int r, lld x) { sum[u] = (sum[u] * x) % p; multag[u] = (multag[u] * x) % p; plutag[u] = (plutag[u] * x) % p; } void plu(int u, int ul, int ur, int ml ,int mr, int x) { if(ml <= ul && mr >= ur) { pludate(u, ul, ur, x); return; } pushdown(u, ur - ul + 1); int mid = ul + ur >> 1; if(ml <= mid) plu(u << 1, ul, mid, ml, mr, x); if(mid + 1 <= mr) plu(u << 1 | 1, mid + 1, ur, ml, mr, x); pushup(u); } void mul(int u, int ul, int ur, int ml, int mr, int x) { if(ml <= ul && mr >= ur) { muldate(u, ul, ur, x); return; } pushdown(u, ur - ul + 1); int mid = ul + ur >> 1; if(ml <= mid) mul(u << 1, ul, mid, ml, mr, x); if(mid + 1 <= mr) mul(u << 1 | 1, mid + 1, ur, ml, mr, x); pushup(u); } lld query(int u, int ul, int ur, int ml, int mr) { if(ml <= ul && mr >= ur) { return sum[u]; } pushdown(u, ur - ul + 1); int mid = ul + ur >> 1; lld s = 0; if(ml <= mid) { s += query(u << 1, ul, mid, ml, mr); s %= p; } if(mr >= mid + 1) { s += query(u << 1 | 1, mid + 1, ur, ml, mr); s %= p; } return s; } int main() { cin >> n >> m >> p; build(1, 1, n); while(m--) { int ord, a, b; lld c; cin >> ord >> a >> b; if(ord == 1) { cin >> c; mul(1, 1, n, a, b, c); } else if(ord == 2) { cin >> c; plu(1, 1, n, a, b, c); } else { cout << (lld) query(1, 1, n, a, b) << endl; } } return 0; }
【模板】树状数组 2
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; typedef long long lld; const int N = 5e5 + 9; int n, m; lld a[N], d[N], id[N]; int lowbit(int x) { return x & (-x); } void modify(lld *t, int i, lld x) { while(i <= n) { t[i] += x; i += lowbit(i); } } lld query(lld *t, int i) { lld sum = 0; while(i) { sum += t[i]; i -= lowbit(i); } return sum; } lld q(int r) { return (lld)query(d, r) * (r + 1) - query(id, r); } int main() { cin >> n >> m; for(int i = 1;i <= n; i ++) { cin >> a[i]; modify(d, i, a[i] - a[i - 1]); modify(id, i, i * (a[i] - a[i - 1])); } while(m--) { lld opt, x, y, z; cin >> opt >> x; if(opt == 1) { cin >> y >> z; modify(d, x, z); modify(id, x, x * z); modify(d, y + 1, -z); modify(id, y + 1, (y + 1) *(-z)); } else { cout << (lld)q(x) - q(x - 1) << endl; } } return 0; }