1. 程式人生 > >UESTC 1073 秋實大哥與線段樹 (線段樹)

UESTC 1073 秋實大哥與線段樹 (線段樹)

put tom typedef ram std amp oid 的人 輸出

“學習本無底,前進莫徬徨。” 秋實大哥對一旁玩手機的學弟說道。

秋實大哥是一個愛學習的人,今天他剛剛學習了線段樹這個數據結構。

為了檢驗自己的掌握程度,秋實大哥給自己出了一個題,同時邀請大家一起來作。

秋實大哥的題目要求你維護一個序列,支持兩種操作:一種是修改某一個元素的值;一種是詢問一段區間的和。

Input

第一行包含一個整數nn,表示序列的長度。

接下來一行包含nn個整數aiai,表示序列初始的元素。

接下來一行包含一個整數mm,表示操作數。

接下來mm行,每行是以下兩種操作之一:

1 x v : 表示將第x個元素的值改為v
2 l r : 表示詢問[l,r]這個區間的元素和

1nmvai1000001≤n,m,v,ai≤100000,1lrn1≤l≤r≤n。

Output

對於每一個22 ll rr操作,輸出一個整數占一行,表示對應的答案。

Sample Input

3
1 2 3
3
2 1 2
1 1 5
2 1 2

Sample Output

3
7
題解:

  這是一道線段樹的裸題。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string
> #include<cmath> #include<set> #include<map> using namespace std; typedef long long LL; inline LL read() { int x=0,f=1;char ch=getchar(); while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();} while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
return x*f; } const int maxn=1e5+5; struct Node { int l,r; LL sum; }seg[maxn<<2]; int num[maxn]; void push_up(int n) { seg[n].sum=seg[n<<1].sum+seg[n<<1|1].sum; } void build(int i,int l,int r) { seg[i].l=l; seg[i].r=r; if(l==r) { seg[i].sum=num[l]; return ; } int mid=(l+r)>>1; build(i<<1,l,mid); build(i<<1|1,mid+1,r); push_up(i); } void updata(int i,int t,int val) { if(seg[i].l==t&&seg[i].r==t) { seg[i].sum=val; return ; } int mid=(seg[i].l+seg[i].r)>>1; if(t<=mid) updata(i<<1,t,val); else updata(i<<1|1,t,val); push_up(i); } LL query(int i,int l,int r) { if(seg[i].l>=l&&seg[i].r<=r) return seg[i].sum; int mid=(seg[i].l+seg[i].r)>>1; if(r<=mid) return query(i<<1,l,r); if(l>mid) return query(i<<1|1,l,r); return query(i<<1,l,mid)+query(i<<1|1,mid+1,r); } int main() { ios::sync_with_stdio(false); int n; cin>>n; for(int i=1;i<=n;i++) cin>>num[i]; build(1,1,n); int t; cin>>t; while(t--) { int q,a,b; cin>>q>>a>>b; if(q==1) updata(1,a,b); else cout<<query(1,a,b)<<endl; } return 0; }

 

UESTC 1073 秋實大哥與線段樹 (線段樹)