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 }
树状数组:
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 }
前缀和:
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 }