ZKW线段树

时间:2021-04-18 18:10:11

简介

zkw线段树虽然是线段树的另一种写法,但是本质上已经和普通的递归版线段树不一样了,是一种介于树状数组和线段树中间的存在,一些功能上的实现比树状数组多,而且比线段树好写且常数小。

普通线段树采用从上到下逐层递归的方式。zkw线段树则是从底层开始,目标直接明确,不需要线段树在确定区间的分治过程。

一些基础题

COGS264 数列操作

树状数组的题,据说模拟也能过hhhh。

单点修改,区间查询。各种数据结构都可搞,用最基本的zkw线段树实现。

//zkw segment tree
//by Cydiater
//2016.12.11
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
#define ll long long
#define up(i,j,n)		for(int i=j;i<=n;i++)
#define down(i,j,n)		for(int i=j;i>=n;i--)
#define cmax(a,b)		a=max(a,b)
#define cmin(a,b)		a=min(a,b)
#define FILE 			"shulie"
const int MAXN=1<<19;
const int LIM=1<<18;
const int M=1<<17;
const int oo=0x3f3f3f3f;
inline int read(){
	char ch=getchar();int x=0,f=1;
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int N,arr[MAXN],MM;
char s[15];
struct zkw_Segment_Tree{
	int t[MAXN];
	void build(){
		up(i,M,LIM-1)t[i]=arr[i-M+1];
		down(dep,16,0)up(i,1<<dep,(1<<(dep+1))-1)t[i]=t[i<<1]+t[i<<1|1];
	}
	int Query(int L,int R){
		L-=1;R+=1;int ans=0;
		for(int S=L+M,T=R+M;S^T^1;S>>=1,T>>=1){
			if(~S&1)	ans+=t[S^1];
			if(T&1)		ans+=t[T^1];
		}
		return ans;
	}
	void Change(int pos,int d){
		for(pos+=M;pos;pos>>=1)t[pos]+=d;
	}
}Tree;
namespace solution{
	void Slove(){
		N=read();
		up(i,1,N)arr[i+1]=read();
		Tree.build();
		MM=read();
		while(MM--){
			scanf("%s",s);
			if(s[0]=='S'){
				int L=read(),R=read();
				printf("%d\n",Tree.Query(L,R));
			}
			else{
				int pos=read(),d=read();
				Tree.Change(pos,d);
			}
		}
	}
}
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	using namespace solution;
	Slove();
	return 0;
}