[线段树]线段树练习五

线 段 树 练 习 题 五 线段树练习题五 线


题目描述

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


样例输入

20 //方格个数
6 //有几组操作
M 1 1 //表示修改,第一个表示格子位置,第二个数表示在原来的基础上加上的数,
M 2 2
M 3 4
M 3 -5
M 6 7
C 2 6 //表示统计 ,第一个数表示起始位置,第二个数表示结束位置


样例输出

8


数据范围

N <= 10000
M <= 1000000


code

#include<stdio.h>
#include<iostream>
using namespace std;
char c;
int n,m,e,z,tr[400005]={0};
void insertt(int t,int a,int b);
int countt(int t,int x,int y,int a,int b);
int main(){
    scanf("%d%d ",&m,&n);
    for(int i=1;i<=n;i++){
    	cin>>c;
		scanf("%d%d",&e,&z); 
        if(c=='M')insertt(1,1,m);
        else{
			printf("%d\n",countt(1,1,m,e,z));
        } 
    }
    return 0;
}
int countt(int t,int x,int y,int a,int b){
	if(y>m)return 0;
	if(x==a and y==b){
		return tr[t];
	}
	int mid=(x+y)/2;
	if(b<=mid){
		return countt(t*2,x,mid,a,b);
	}
	else if(a>mid){
		return countt(t*2+1,mid+1,y,a,b);
	}
	else{
		return countt(t*2,x,mid,a,mid)+countt(t*2+1,mid+1,y,mid+1,b);
	}
}
void insertt(int t,int a,int b){
	if(a==b){
		tr[t]+=z;
		return ;
	}
	int mid=(a+b)/2;
	if(e<=mid){
		insertt(t*2,a,mid);
	}
	else{
		insertt(t*2+1,mid+1,b);
	}
	tr[t]+=z;
}

posted @ 2020-08-10 09:24  unknown_future  阅读(53)  评论(0编辑  收藏  举报