1. 程式人生 > >51nod 1081 子段求和(線段樹 | 樹狀陣列 | 字首和)

51nod 1081 子段求和(線段樹 | 樹狀陣列 | 字首和)

題目連結:子段求和

題意:n個數字序列,m次詢問,每次詢問從第p個開始L長度序列的子段和為多少。

題解:線段樹區間求和 | 樹狀陣列區間求和

線段樹:

 1 #include <cstdio>
 2 #define LC(a) ((a<<1))
 3 #define RC(a) ((a<<1)+1)
 4 #define MID(a,b) ((a+b)>>1)
 5 using namespace std;
 6 
 7 typedef long long ll;
 8 const int N=5e4*4
; 9 ll ans=0; 10 11 struct node{ 12 ll l,r,sum; 13 }tree[N]; 14 15 void pushup(ll p){ 16 tree[p].sum=tree[LC(p)].sum+tree[RC(p)].sum; 17 } 18 19 void build(ll p,ll l,ll r){ 20 tree[p].l=l; 21 tree[p].r=r; 22 tree[p].sum=0; 23 if(l==r){ 24 scanf("%lld",&tree[p].sum);
25 return; 26 } 27 build(LC(p),l,MID(l,r)); 28 build(RC(p),MID(l,r)+1,r); 29 pushup(p); 30 } 31 32 void query(ll p,ll l, ll r){ 33 if(r<tree[p].l||l>tree[p].r) return; 34 if(l<=tree[p].l&&r>=tree[p].r){ 35 ans+=tree[p].sum; 36 return
; 37 } 38 query(LC(p),l,r); 39 query(RC(p),l,r); 40 } 41 42 int main(){ 43 44 ll n,q; 45 scanf("%lld",&n); 46 build(1,1,n); 47 scanf("%lld",&q); 48 while(q--){ 49 ans=0; 50 ll st,len; 51 scanf("%lld%lld",&st,&len); 52 query(1,st,st+len-1); 53 printf("%lld\n",ans); 54 } 55 56 return 0; 57 }
Code

樹狀陣列:

 1 #include <cstdio>
 2 #define low(i) ((i)&(-i))
 3 using namespace std;
 4 
 5 const int N=5e4+10;
 6 typedef long long ll;
 7 ll a[N];
 8 int n,q;
 9 
10 struct TreeArray {
11     ll c[N];
12     void add(int pos,ll v) {
13         for(int i=pos;i<=n;i+=low(i)) c[i]+=v;
14     }
15     ll query(int pos) {
16         ll res=0;
17         for(int i=pos;i;i-=low(i)) res+=c[i];
18         return res;
19     }
20 }p;
21 
22 int main(){
23     scanf("%d",&n);
24     for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
25     for(int i=1;i<=n;i++) p.add(i,a[i]);
26     scanf("%d",&q);
27     while(q--){
28         int st,len;
29         scanf("%d%d",&st,&len);
30         printf("%lld\n",p.query(st+len-1)-p.query(st-1));
31     }
32     return 0;
33 }
Code

字首和:

 1 #include <cstdio>
 2 #define low(i) ((i)&(-i))
 3 using namespace std;
 4 
 5 const int N=5e4+10;
 6 typedef long long ll;
 7 ll sum[N];
 8 int n,q;
 9 
10 int main(){
11     sum[0]=0;
12     scanf("%d",&n);
13     for(int i=1;i<=n;i++){
14         scanf("%lld",&sum[i]);
15         sum[i]+=sum[i-1];
16     }
17     scanf("%d",&q);
18     while(q--){
19         int st,len;
20         scanf("%d%d",&st,&len);
21         printf("%lld\n",sum[st+len-1]-sum[st-1]);
22     }
23     return 0;
24 }
Code