POJ 3468

一道线段树裸题

区间修改,区间查询

也是我的第一份线段树

但要注意结果不爆int 不代表过程不爆int

所以一定要开long long

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=5000000;
inline long long read(){
	int x=0,f=1,ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
inline int cread(){
	int ch=getchar();
	while(ch<'A'||ch>'Z') ch=getchar();
	return ch;
}
long long data[MAXN],tree[MAXN];
inline void pushdown(int id,int l,int r){
	data[id]+=(r-l+1)*tree[id];
	tree[id<<1]+=tree[id];
	tree[id<<1|1]+=tree[id];
	tree[id]=0;
}
inline void add(int id,int l,int r,int sl,int sr,long long x){
	pushdown(id,l,r);
	if(l>sr||r<sl) return ;
	if(sl<=l&&r<=sr){
		tree[id]=x;
		pushdown(id,l,r);
		return ;
	}
	int mid=(l+r)>>1;
	add(id<<1,l,mid,sl,sr,x);
	add(id<<1|1,mid+1,r,sl,sr,x);
	data[id]=data[id<<1]+data[id<<1|1];
}
inline long long query(int id,int l,int r,int sl,int sr){
	pushdown(id,l,r);
	if(l>sr||r<sl) return 0;
	if(sl<=l&&r<=sr) return data[id];
	int mid=(l+r)>>1;
	return query(id<<1,l,mid,sl,sr)+query(id<<1|1,mid+1,r,sl,sr);
}
int main(){
	int n=read(),q=read();
	for(int i=1;i<=n;i++){
		long long x=read();
		add(1,1,n,i,i,x);
	}
	for(int i=1;i<=q;i++){
		int c=cread();
		if(c=='Q'){
			int l=read(),r=read();
			printf("%lld\n",query(1,1,n,l,r));
		}
		if(c=='C'){
			int l=read(),r=read();
			long long x=read();
			add(1,1,n,l,r,x);
		}
	}
	return 0;
}

  

posted @ 2018-09-30 22:38  古城独钓  阅读(143)  评论(0编辑  收藏  举报