51nod 1081 子段求和

给出一个长度为N的数组,进行Q次查询,查询从第i个元素开始长度为l的子段所有元素之和。
例如,1 3 7 9 -1,查询第2个元素开始长度为3的子段和,1 {3 7 9} -1。3 + 7 + 9 = 19,输出19。
 

输入

第1行:一个数N,N为数组的长度(2 <= N <= 50000)。
第2 至 N + 1行:数组的N个元素。(-10^9 <= N[i] <= 10^9)
第N + 2行:1个数Q,Q为查询的数量。
第N + 3 至 N + Q + 2行:每行2个数,i,l(1 <= i <= N,i + l <= N)

输出

共Q行,对应Q次查询的计算结果。

输入样例

5
1
3
7
9
-1
4
1 2
2 2
3 2
1 5

输出样例

4
10
16
19

前缀和代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#define MAX 50000
#define DMAX 10000
using namespace std;
typedef long long ll;
int n,q,a,b;
ll sum[MAX + 1];
int main() {
    scanf("%d",&n);
    for(int i = 1;i <= n;i ++) {
        scanf("%d",&a);
        sum[i] = sum[i - 1] + a;
    }
    scanf("%d",&q);
    for(int i = 0;i < q;i ++) {
        scanf("%d%d",&a,&b);
        printf("%lld\n",sum[a + b - 1] - sum[a - 1]);
    }
}

st代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#define MAX 50000
#define DMAX 10000
using namespace std;
typedef long long ll;
int n,q,a,b;
ll dp[MAX + 1][20];
void init() {
    for(int j = 1;j <= 18;j ++) {
        for(int i = 0;i < n;i ++){
            if(i + (1 << j) <= n) {
                dp[i][j] = dp[i][j - 1] + dp[i + (1 << (j - 1))][j - 1];
            }
        }
    }
}
ll query(int x,int y) {
    ll ans = 0;
    while(y) {
        int d = (int)log2(y);
        ans += dp[x][d];
        x += 1 << d;
        y -= 1 << d;
    }
    return ans;
}
int main() {
    scanf("%d",&n);
    for(int i = 0;i < n;i ++) {
        scanf("%lld",&dp[i][0]);
    }
    init();
    scanf("%d",&q);
    for(int i = 0;i < q;i ++) {
        scanf("%d%d",&a,&b);
        printf("%lld\n",query(a - 1,b));
    }
}

线段树代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#define MAX 50000
#define DMAX 10000
const int maxn = (1 << (int)(log2(50000) + 1)) * 2 + 1;
using namespace std;
typedef long long ll;

int n,q,a,b;
ll tree[maxn];
void build(int l,int r,int t) {
    if(l == r) scanf("%lld",&tree[t]);
    else {
        int mid = (l + r) / 2;
        build(l,mid,t << 1);
        build(mid + 1,r,t << 1 | 1);
        tree[t] = tree[t << 1] + tree[t << 1 | 1];
    }
}
ll query(int x,int y,int l,int r,int t) {
    if(l >= x && r <= y) return tree[t];
    int mid = (l + r) / 2;
    ll ans = 0;
    if(mid >= x) ans += query(x,y,l,mid,t << 1);
    if(mid < y) ans += query(x,y,mid + 1,r,t << 1 | 1);
    return ans;
}
int main() {
    scanf("%d",&n);
    build(1,n,1);
    scanf("%d",&q);
    for(int i = 0;i < q;i ++) {
        scanf("%d%d",&a,&b);
        printf("%lld\n",query(a,a + b - 1,1,n,1));
    }
}

猜你喜欢

转载自www.cnblogs.com/8023spz/p/10022398.html