N (≤50,000) 個營地,初始人數給定。支持 M (≤40,000) 次操作:
Add i j:第 i 營地增加 j 人
Sub i j:第 i 營地減少 j 人
Query i j:查詢區間 [i,j] 總人數
End:本組數據結束
與 HDU 1754(區間最大值)類似,區別在於:
- 節點值:區間和(而非最大值)
- 合併:sum = left.sum + right.sum
- 更新:val += delta(增量更新)
#includeusing namespace std; const int MAXN = 50005; struct SegTree { int sum[4*MAXN], L[4*MAXN], R[4*MAXN]; int a[MAXN]; void build(int o, int l, int r) { L[o]=l; R[o]=r; if (l==r) { sum[o]=a[l]; return; } int mid=(l+r)/2; build(o*2,l,mid); build(o*2+1,mid+1,r); sum[o]=sum[o*2]+sum[o*2+1]; } void update(int o, int pos, int delta) { if (L[o]==pos && R[o]==pos) { sum[o]+=delta; return; } int mid=(L[o]+R[o])/2; if (pos<=mid) update(o*2,pos,delta); else update(o*2+1,pos,delta); sum[o]=sum[o*2]+sum[o*2+1]; } int query(int o, int l, int r) { if (l<=L[o] && R[o]<=r) return sum[o]; int mid=(L[o]+R[o])/2, res=0; if (l<=mid) res+=query(o*2,l,r); if (r>mid) res+=query(o*2+1,l,r); return res; } } st; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; for (int cas=1; cas<=T; ++cas) { int N; cin >> N; for (int i=1; i<=N; ++i) cin >> st.a[i]; st.build(1,1,N); cout << "Case " << cas << ":\n"; string op; while (cin >> op) { if (op[0]=='E') break; int x,y; cin >> x >> y; if (op[0]=='A') st.update(1,x,y); else if (op[0]=='S') st.update(1,x,-y); else if (op[0]=='Q') cout << st.query(1,x,y) << '\n'; } } return 0; }
A/S/Q/ESub 操作傳入負增量 -y 復用 updateCase i:此題是線段樹「區間求和 + 單點增量更新」的標準模板,與區間最值題結構幾乎相同,只需修改合併邏輯與更新方式。