小水题
话说rayment大佬嘘寒问暖两天,差点教会我怎么用splay求区间和。这题我差点就下狠手使用splay了。
线段树1的退化版,change区间变成了change一个数,延迟标记?不存在!
所以我们只需要简单建一棵线段树,然后轻松模拟就好了。建树其实只需要将树的区间搞出来,区间和由于初始值为0,所以根本不需要求。
#include <bits/stdc++.h>
#define maxn 100010
using namespace std;
struct segment_tree{
int l,r;
int v;
}t[4*maxn];
void build(int x,int l,int r){
t[x].l=l;t[x].r=r;
t[x].v=0;//因为初始值是0,所以建树不需要那么麻烦
int mid=(l+r)/2;
if (l==r)return ;
build(x*2,l,mid);
build(x*2+1,mid+1,r);//建树
}
int y,z;
void change(int x,int l,int r){
int mid=(l+r)/2;
t[x].v+=z;//只改变一个值,所以每个包含只需要加一遍
if (l==r)return ;
if (mid>=y)change(x*2,l,mid);
else change(x*2+1,mid+1,r);
}
int ask(int x,int l,int r){
if (l<=t[x].l&&r>=t[x].r)return t[x].v;//如果完全包含,则直接返回
int mid=(t[x].l+t[x].r)/2;
int v=0;
if (l<=mid) v+=ask(x*2,l,r);
if (r>mid) v+=ask(x*2+1,l,r);//递归
return v;//询问区间和
}
int main(){
int i,j,n,m;
cin>>n;
build(1,1,n);
cin>>m;
for (i=1;i<=m;i++){
char x;
cin>>x>>y>>z;
if (x=='x')change(1,1,n);
else cout<<ask(1,y,z)<<endl;
}
return 0;
}//主函数部分,没什么意义
线段树板子题,刚学线段树的oier也可以直接切了,加点经验。