POJ-3468 A Simple Problem with Integers
阿新 • • 發佈:2022-05-19
A Simple Problem with Integers
線段樹 || 分塊
模板題
線段樹:
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int maxn = 2e5 + 10; ll num[maxn]; struct node { int l; int r; ll val; ll lazy; }tree[maxn * 4]; void build(int x, int l, int r) { tree[x].l = l; tree[x].r = r; tree[x].lazy = 0; if (l == r) { tree[x].val = num[l]; return; } int mid = l + r >> 1; build(x << 1, l, mid); build(x << 1 | 1, mid + 1, r); tree[x].val = tree[x << 1].val + tree[x << 1 | 1].val; } void pushdown(int x) { if (tree[x].lazy) { int a = x << 1; int b = x << 1 | 1; tree[a].val += (tree[a].r - tree[a].l + 1) * tree[x].lazy; tree[b].val += (tree[b].r - tree[b].l + 1) * tree[x].lazy; tree[a].lazy += tree[x].lazy; tree[b].lazy += tree[x].lazy; tree[x].lazy = 0; } } void update(int x, int l, int r, int val) { if (tree[x].l >= l && tree[x].r <= r) { tree[x].val += (tree[x].r - tree[x].l + 1) * val; tree[x].lazy += val; return; } pushdown(x); int mid = tree[x].l + tree[x].r >> 1; if (l <= mid) update(x << 1, l, r, val); if (r > mid) update(x << 1 | 1, l, r, val); tree[x].val = tree[x << 1].val + tree[x << 1 | 1].val; } ll query(int x, int l, int r) { if (tree[x].l >= l && tree[x].r <= r) return tree[x].val; pushdown(x); ll ans = 0; int mid = tree[x].l + tree[x].r >> 1; if (l <= mid) ans += query(x << 1, l, r); if (r > mid) ans += query(x << 1 | 1, l, r); return ans; } int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%lld", &num[i]); build(1, 1, n); for (int i = 0; i < m; i++) { char s[5]; int a, b; scanf("%s%d%d", s, &a, &b); if (a > b)swap(a, b); if (s[0] == 'Q') printf("%lld\n", query(1, a, b)); else if (s[0] == 'C') { int c; scanf("%d", &c); update(1, a, b, c); } } }
分塊:(參考的是藍書的程式碼)
#include <iostream> #include <cstdio> #include <cmath> using namespace std; typedef long long ll; const int maxn = 1e5 + 10; ll num[maxn], sum[maxn], add[maxn], pos[maxn], R[maxn], L[maxn]; void update(int l, int r, ll val) { int p = pos[l], q = pos[r]; if(p == q) { for(int i=l; i<=r; i++) num[i] += val; sum[q] += (r - l + 1) * val; } else { for(int i=p+1; i<q; i++) add[i] += val; for(int i=l; i<=R[p]; i++) num[i] += val; sum[p] += val * (R[p] - l + 1); for(int i=L[q]; i<=r; i++) num[i] += val; sum[q] += val * (r - L[q] + 1); } } ll query(int l, int r) { ll ans = 0; int p = pos[l], q = pos[r]; if(p == q) { for(int i=l; i<=r; i++) ans += num[i]; ans += add[p] * (r - l + 1); } else { for(int i=p+1; i<q; i++) ans += add[i] * (R[i] - L[i] + 1) + sum[i]; for(int i=l; i<=R[p]; i++) ans += num[i]; ans += add[p] * (R[p] - l + 1); for(int i=L[q]; i<=r; i++) ans += num[i]; ans += add[q] * (r - L[q] + 1); } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, m; cin >> n >> m; for(int i=1; i<=n; i++) cin >> num[i]; int t = (double)sqrt((double)n); for(int i=1; i<=t; i++) { L[i] = R[i-1] + 1; R[i] = i * t; } if(R[t] < n) { t++; L[t] = R[t-1] + 1; R[t] = n; } for(int i=1; i<=t; i++) { for(int j=L[i]; j<=R[i]; j++) { sum[i] += num[j]; pos[j] = i; } } while(m--) { char x; int l, r; cin >> x >> l >> r; if(x == 'C') { ll val; cin >> val; update(l, r, val); } else cout << query(l, r) << endl; } return 0; }