线段树解法
注意数组大小,一般我们用线段树,都开四倍空间。但是这道题数据量是一百万,四倍开不了
所以我们就不能开四倍,而要计算一下空间,避免浪费。
计算方法就是 1000000 找到2的n次方刚好大于一百万的那个数 就是2的20次方是1048576
然后再拿1048576 x 2 = 2097152 得到的这个数就是所需的大概空间
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=2e6+7;
const int maxnode=2097152;
struct NODE{
int left,right,value;
}node[maxnode];
int father[maxn];
int n,m,x,y,g;
void BuildTree(int i,int left,int right){
node[i].left=left;
node[i].right=right;
node[i].value=0;
if(left==right){
father[left]=i;return ;
}
BuildTree(i<<1,left,(left+right)/2);
BuildTree((i<<1)+1,(left+right)/2+1,right);
}
void UpdateTree(int ri){
if(ri==1) return ;
int fi=ri/2;
int a=node[fi<<1].value;
int b=node[(fi<<1)+1].value;
node[fi].value=a+b;//这道题是求区间和
UpdateTree(ri/2);
}
int ans;
void Query(int i,int l,int r){
if(node[i].left==l&&node[i].right==r){
ans+=node[i].value;return ;//这道题是求区间和
}
i=i<<1;
if(l<=node[i].right){
if(r<=node[i].right) Query(i,l,r);
else Query(i,l,node[i].right);
}
i++;
if(r>=node[i].left){
if(l>=node[i].left) Query(i,l,r);
else Query(i,node[i].left,r);
}
}
int main(){
scanf("%d%d",&n,&m);
BuildTree(1,1,n);
for(int i=1;i<=n;i++){
scanf("%d",&g);
node[father[i]].value=g;
UpdateTree(father[i]);
}
char op[20];
while(m--){
scanf(" %s%d%d",&op,&x,&y);
ans=0;
if(op[0]=='Q'){
Query(1,x,y);printf("%d\n",ans);
}
else{
node[father[x]].value+=y;//这里是新增杀敌数
UpdateTree(father[x]);
}
}
return 0;
}