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 }
View 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 }
View 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 }
View Code

 

posted @ 2018-11-18 22:13  pavtlly  阅读(279)  评论(0编辑  收藏  举报