HDU-6315:Naive Operations(线段树+思维)
题意:
In a galaxy far, far away, there are two integer sequence a and b of length n.
b is a static permutation of 1 to n. Initially a is filled with zeroes.
There are two kind of operations:
1. add l r: add one for al,al+1...ar
2. query l r: query ∑ri=l⌊ai/bi⌋
题解:每次更新时,直接将 b 数组的对应区间都减一,如果发现有零,就将对应位置的答案加一并重置回原b数组对应的数。
#include <bits/stdc++.h> using namespace std; const double EPS = 1e-6; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; const int maxn = 1e5 + 10; int n, m, x, y; int a[maxn]; char q[maxn]; struct Node{int mi, sum, add;} T[maxn<<2]; void Build(int l, int r, int rt) { if(l == r){ T[rt].mi = a[l]; T[rt].sum = 0; T[rt].add = 0; return ; } int mid = (l + r) >> 1; Build(l, mid, rt<<1); Build(mid + 1, r, rt<<1|1); T[rt].mi = min(T[rt<<1].mi, T[rt<<1|1].mi); T[rt].sum = T[rt<<1].sum + T[rt<<1|1].sum; T[rt].add = T[rt<<1].add + T[rt<<1|1].add; } void Pushdown(int rt, int l, int r) { if(!T[rt].add) return; int mid = (l + r) >> 1; T[rt<<1].mi += T[rt].add; T[rt<<1|1].mi += T[rt].add; T[rt<<1].add += T[rt].add; T[rt<<1|1].add += T[rt].add; T[rt].add = 0; } void Update(int L, int R, int l, int r, int rt, bool ok) { if(L <= l && r <= R){ if(ok){ T[rt].add--; T[rt].mi--; } if(T[rt].mi > 0) return; if(l == r){ if(T[rt].mi == 0) T[rt].sum++, T[rt].mi = a[l]; return; } ok = false; } Pushdown(rt, l, r); int mid = (l + r) >> 1; if(L <= mid) Update(L, R, l, mid, rt<<1, ok); if(R > mid) Update(L, R, mid + 1, r, rt<<1|1, ok); T[rt].mi = min(T[rt<<1].mi, T[rt<<1|1].mi); T[rt].sum = T[rt<<1].sum + T[rt<<1|1].sum; } int Query(int L, int R, int l, int r, int rt) { if(L <= l && r <= R) return T[rt].sum; int ans = 0, mid = (l + r) >> 1; if(L <= mid) ans += Query(L, R, l, mid, rt<<1); if(R > mid) ans += Query(L, R, mid + 1, r, rt<<1|1); return ans; } int main() { while(scanf("%d%d", &n, &m) != EOF){ for(int i = 1; i <= n; i++) scanf("%d", &a[i]); Build(1, n, 1); while(m--){ scanf("%s%d%d", q, &x, &y); if(q[0] == 'a') Update(x, y, 1, n, 1, true); else printf("%d\n", Query(x, y, 1, n, 1)); } } return 0; }