码迷,mamicode.com
首页 > 其他好文 > 详细

codevs1080线段树练习

时间:2016-07-15 08:04:07      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:

题目描述 Description

一行N个方格,开始每个格子里都有一个整数。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N<100000,,提问和修改的总数m<10000条。

输入描述 Input Description

输入文件第一行为一个整数N,接下来是n行n个整数,表示格子中原来的整数。接下一个正整数m,再接下来有m行,表示m个询问,第一个整数表示询问代号,询问代号1表示增加,后面的两个数x和A表示给位置X上的数值增加A,询问代号2表示区间求和,后面两个整数表示a和b,表示要求[a,b]之间的区间和。

输出描述 Output Description

共m行,每个整数

样例输入 Sample Input

6

3

4

1 3 5

2 1 4

1 1 9

2 2 6

样例输出 Sample Output

22

22

数据范围及提示 Data Size & Hint

1≤N≤100000, m≤10000 。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
const int maxn = 100050;
int n,m,num[maxn],c[maxn];
int lowbit(int x){
    return x&(-x);
}
void change(int p,int x){
    for(int i = p;i <= n;i += lowbit(i)) c[i] += x;
}
int query(int a,int b){
    int sum = 0;
    for(int i = b;i;i -= lowbit(i)) sum += c[i];
    for(int i = a-1;i;i -= lowbit(i)) sum -= c[i];
    return sum;
}
int main(){
    cin>>n;
    int cmd,a,b;
    for(int i = 1;i <= n;i++){
        scanf("%d",&num[i]);
        for(int j = i-lowbit(i)+1;j<=i;j++) c[i] += num[j];
    }
    cin>>m;
    for(int i = 1;i <= m;i++){
        scanf("%d%d%d",&cmd,&a,&b);
        if(cmd == 1) change(a,b);
        else printf("%d\n",query(a,b));
    }
    return 0;
}
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 
using namespace std;
const int maxn = 100050;
int n,m,a[maxn<<4],sum[maxn<<4];
void pushup(int rt){
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
} 
void buildtree(int l,int r,int rt){
    if(l == r){
        sum[rt] = a[l];
        return;
    }
    int m = (l+r) >> 1;
    buildtree(lson);
    buildtree(rson);
    pushup(rt);
}
void change(int p,int x,int l,int r,int rt){
    if(l == r){
        sum[rt] += x;
        return;
    }
    int m = (l+r) >> 1;
    if(p <= m) change(p,x,lson);
    else change(p,x,rson);
    pushup(rt);
    return;
}
int query(int L,int R,int l,int r,int rt){
    if(L <= l && r <= R){
        return sum[rt];
    }
    int m = (l+r) >> 1;
    int ret = 0;
    if(L <= m) ret += query(L,R,lson);
    if(R > m) ret += query(L,R,rson);
    return ret;
}
int main(){
    cin>>n;
    for(int i = 1;i <= n;i++){
        scanf("%d",&a[i]);
    }
    buildtree(1,n,1);
    cin>>m;
    int cmd,a,b;
    for(int i = 1;i <= m;i++){
        scanf("%d%d%d",&cmd,&a,&b);
        if(cmd == 1) change(a,b,1,n,1);
        else printf("%d\n",query(a,b,1,n,1));
    }
    return 0;
} 

 

codevs1080线段树练习

标签:

原文地址:http://www.cnblogs.com/hyfer/p/5672282.html

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