码迷,mamicode.com
首页 > 编程语言 > 详细

树状数组模板题 P1904

时间:2018-11-30 17:28:23      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:class   str   return   can   增加   tput   一个   \n   amp   

Description

给定一个长度为n的整数数组A[1]、A[2]、…、A[n](-10^9<=A[i]<=10^9),和m个操作: 操作1:1 i x 把A[i]的值增加x(-10^3<=A[i]<=10^3); 操作2:2 i j 查询当前序列的连续子序列A[i]..A[j]的和。

Input

第一行包含两个整数n和m,表示数组有n个元素,m表示有m个操作;接下来的一行包含n个整数,第i个整数表示A[i];再接下来的m行,每行表示一个操作。

Output

按输入顺序输出操作2的结果。

Hint

反正要用long long

Solution

嗯,这个题,告诉我们,位运算要打括号。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define maxn 100005
#define lowbit(x) (x&(-x))
using namespace std;
long long c[maxn];
long long n,m,z,u,z2,ans1,ans2,ans;
void doadd(long long x,long long y){
    while(x<=n){
        c[x]=c[x]+y;
        x=x+lowbit(x);
    }
}
long long sets(long long x){
    long long s=0;
    while(x>0){
        s+=c[x];
        x-=lowbit(x);
    }
    return s;
}
int main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&z);
        doadd(i,z);
    }
    for(int j=1;j<=m;j++){
        scanf("%lld",&u);
        if(u==1){
            scanf("%lld%lld",&z2,&z);
            doadd(z2,z);
        }
        else{
            scanf("%lld%lld",&z2,&z);
            ans1=sets(z);
            ans2=sets(z2-1);
            ans=ans1-ans2;
            printf("%lld\n",ans);
        }
    }
    return 0;
}

树状数组模板题 P1904

标签:class   str   return   can   增加   tput   一个   \n   amp   

原文地址:https://www.cnblogs.com/virtual-north-Illya/p/10045147.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!