题解 luogu P2068 【统计和】

小水题

话说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也可以直接切了,加点经验。

猜你喜欢

转载自blog.csdn.net/qq_39441542/article/details/84675021
今日推荐