zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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
    ",query(a,a + b - 1,1,n,1));
        }
    }
  • 相关阅读:
    cookie
    sql 语句
    页面宽高
    分页
    asp.net中如何防止用户重复点击提交按钮
    小试简单工厂模式之简单计算器
    用函数实现交换的疑问
    结构体变量输入输出的问题
    scanf函数输入float数需要注意的问题
    oracle学习手记(1)
  • 原文地址:https://www.cnblogs.com/8023spz/p/10022398.html
Copyright © 2011-2022 走看看