---
# System prepended metadata

title: 2d segment tree
tags: [codebook]

---

---
tags: codebook
---

# 2d segment tree

**CSES - Forest Queries II**

```cpp=
constexpr int maxn=1e3+5;
int arr[(maxn+1)<<2][(maxn+1)<<2];

#define xm ((xl+xr)>>1)
#define ym ((yl+yr)>>1)
void _build(auto& v,int xi,int xl,int xr,int yi=1,int yl=0,int yr=maxn){
	if(yr-yl==1){
		if(xr-xl==1){
			if(xl<int(v.size())&&yl<int(v.size())) 
				arr[xi][yi]=v[xl][yl];
		}else
			arr[xi][yi]=arr[xi<<1][yi]+arr[xi<<1|1][yi];
		return;
	}
	_build(v,xi,xl,xr,yi<<1,yl,ym),_build(v,xi,xl,xr,yi<<1|1,ym,yr);
	arr[xi][yi]=arr[xi][yi<<1]+arr[xi][yi<<1|1];
}
void build(auto& v,int xi=1,int xl=0,int xr=maxn){
	if(xr-xl>1)
		build(v,xi<<1,xl,xm),build(v,xi<<1|1,xm,xr);
	_build(v,xi,xl,xr);
}
int _query(int yql,int yqr,int xi,int yi=1,int yl=0,int yr=maxn){
	if(yqr<=yl||yr<=yql) return 0;
	// debug(yl,yr);
	if(yql<=yl&&yr<=yqr) return arr[xi][yi];
	return _query(yql,yqr,xi,yi<<1,yl,ym)+_query(yql,yqr,xi,yi<<1|1,ym,yr);
}
int query(int xql,int xqr,int yql,int yqr,int xi=1,int xl=0,int xr=maxn){
	if(xqr<=xl||xr<=xql) return 0;
	// debug(xl,xr);
	if(xql<=xl&&xr<=xqr) return _query(yql,yqr,xi);
	return query(xql,xqr,yql,yqr,xi<<1,xl,xm)+query(xql,xqr,yql,yqr,xi<<1|1,xm,xr);
}
void _update(int yp,int xi,int xl,int xr,int yi=1,int yl=0,int yr=maxn){
	if(yp<yl||yr<=yp) return;
	if(yr-yl==1){
		if(xr-xl==1)
			arr[xi][yi]^=1;
		else
			arr[xi][yi]=arr[xi<<1][yi]+arr[xi<<1|1][yi];
		return;
	}
	_update(yp,xi,xl,xr,yi<<1,yl,ym),_update(yp,xi,xl,xr,yi<<1|1,ym,yr);
	arr[xi][yi]=arr[xi][yi<<1]+arr[xi][yi<<1|1];
}
void update(int xp,int yp,int xi=1,int xl=0,int xr=maxn){
	if(xp<xl||xr<=xp) return;
	if(xr-xl>1)
		update(xp,yp,xi<<1,xl,xm),update(xp,yp,xi<<1|1,xm,xr);
	_update(yp,xi,xl,xr);
}
void _print(auto& v,int xl,int xi,int yi=1,int yl=0,int yr=maxn){
	if(yr-yl==1){if(yl<int(v.size())) debug(xl,yl,arr[xi][yi]);return;}
	_print(v,xl,xi,yi<<1,yl,ym),_print(v,xl,xi,yi<<1|1,ym,yr);
}
void print(auto& v,int xi=1,int xl=0,int xr=maxn){
	if(xr-xl>1)
		print(v,xi<<1,xl,xm),print(v,xi<<1|1,xm,xr);
	else
		if(xl<int(v.size())) _print(v,xl,xi);
}
#undef xm
#undef ym

inline void solve() {
	int n,m; cin>>n>>m;
	V<V<int>> v(n,V<int>(n));
	for(int i=0;i<n;i++){
		string str;cin>>str;
		for(int j=0;j<n;j++)
			v[i][j]=(str[j]=='*');
	}
	build(v);
	// cerr<<query(0,n,0,n)<<endl;
	// cerr<<"poop"<<endl;
	while(m--){
		int op,x1,x2,y1,y2; cin>>op;
		switch(op){
		case 1:
			cin>>x1>>y1,x1--,y1--;
			update(x1,y1);
			break;
		case 2:
			cin>>x1>>y1>>x2>>y2,x1--,y1--;
			cout<<query(x1,x2,y1,y2)<<endl;
			break;
		}
	}
}
```