zoukankan      html  css  js  c++  java
  • 树状数组

    终于懂了......

    传送门1

    传送门2

    树状数组

    题目描述

    如题,已知一个数列,你需要进行下面两种操作:

    1.将某一个数加上x

    2.求出某区间每一个数的和

    输入输出格式

    输入格式:

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含3或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x k 含义:将第x个数加上k

    操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

    输出格式:

    输出包含若干行整数,即为所有操作2的结果。

    输入输出样例

    输入样例#1:
    5 5
    1 5 4 2 3
    1 1 3
    2 2 5
    1 3 -1
    1 4 2
    2 1 4
    输出样例#1:
    14
    16

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=10000,M<=10000

    对于100%的数据:N<=500000,M<=500000

    【思路】

    单点修改 区间查询

    【code】

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,m,a,b,c,x;
    int tree[500002];
    void add(int pos,int x)
    {
        while(pos<=n)
        {
            tree[pos]+=x;
            pos+=pos&-pos;
        }
    }
    int sum(int x,int y)
    {
        x--;
        int sum1=0,sum2=0;
        while(x)
        {
            sum1+=tree[x];
            x-=x&-x;
        }
        while(y)
        {
            sum2+=tree[y];
            y-=y&-y;
        }
        return sum2-sum1;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            add(i,x);
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(a==1)add(b,c);
            else
            printf("%d
    ",sum(b,c));
        }
        return 0;
     } 

    题目描述

    如题,已知一个数列,你需要进行下面两种操作:

    1.将某区间每一个数数加上x

    2.求出某一个数的和

    输入输出格式

    输入格式:

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含2或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

    操作2: 格式:2 x 含义:输出第x个数的值

    输出格式:

    输出包含若干行整数,即为所有操作2的结果。

    输入输出样例

    输入样例#1:
    5 5
    1 5 4 2 3
    1 2 4 2
    2 3
    1 1 5 -1
    1 3 5 7
    2 4
    输出样例#1:
    6
    10

    【思路】
    区间修改
    单点查询
    【code】
    #include<iostream>
    #include<cstdio>
    using namespace std;
    int tree[500001];
    int n,m,a,b,c,pre,d,x;
    void add(int pos,int x)
    {
        
        while(pos<=n)
        {
          tree[pos]+=x;
          pos+=pos&-pos;
        }
    }
    int sum(int x)
    {
        int sum=0;
        while(x)
        {
            sum+=tree[x];
            x-=x&-x;
        }
        return sum;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            pre=x;
            scanf("%d",&x);
            add(i,x-pre);
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&a);
            if(a==1)
            {
                scanf("%d%d%d",&b,&c,&d);
                add(b,d);
                add(c+1,-d);
            }
            else
            {
                scanf("%d",&b);
                printf("%d
    ",sum(b));
            }
        }
        return 0;
    }
    
    
    

    学习博客:

    http://www.cnblogs.com/jsawz/p/6745151.html

    http://blog.csdn.net/int64ago/article/details/7429868
  • 相关阅读:
    UVA
    UVA
    模板——扩展欧几里得算法(求ax+by=gcd的解)
    UVA
    模板——2.2 素数筛选和合数分解
    模板——素数筛选
    Educational Codeforces Round 46 (Rated for Div. 2)
    Educational Codeforces Round 46 (Rated for Div. 2) E. We Need More Bosses
    Educational Codeforces Round 46 (Rated for Div. 2) D. Yet Another Problem On a Subsequence
    Educational Codeforces Round 46 (Rated for Div. 2) C. Covered Points Count
  • 原文地址:https://www.cnblogs.com/zzyh/p/6992148.html
Copyright © 2011-2022 走看看