HDU-1540 Tunnel warfare

维护每个区间左端点 能向右走到的最大距离,右端点能向左走到的最大距离

查询的时候,如果当前查询的节点在左子树的rmax里面话,就返回相应的反正继续递归

若位于右子树的话同理可以得到结果

#include
using namespace std;
const int N = 2e5+10;
struct Segment{
	int l,r;
	int lmax,rmax;
}tr[N<<2];
int n,m;


void pushup(int u){
	Segment &root = tr[u],&left = tr[u<<1],&right = tr[u<<1|1];
	root.lmax = left.lmax + (left.lmax == left.r-left.l+1?right.lmax:0);
	root.rmax = right.rmax + (right.rmax == right.r-right.l+1?left.rmax:0);
}


void build(int u,int l,int r){
	tr[u] = {l,r,1,1};
	if(l==r)return;
	int mid = l+r>>1;
	build(u<<1,l,mid),build(u<<1|1,mid+1,r);
	pushup(u);
}

void modify(int u,int x,int c){
	if(tr[u].l==x && tr[u].r==x){
		tr[u].lmax = tr[u].rmax = c;
		return;
	}
	
	int mid = tr[u].l+tr[u].r>>1;
	if(x<=mid)modify(u<<1,x,c);
	if(x>mid)modify(u<<1|1,x,c);
	pushup(u);
}

int query(int u,int x){
	
	if(tr[u].l==tr[u].r)return tr[u].lmax;
	int mid = tr[u].l+tr[u].r>>1;
	
	if(x<=mid){
		if(x>=tr[u<<1].r-tr[u<<1].rmax+1)
		 return tr[u<<1].rmax + tr[u<<1|1].lmax;
		
		return query(u<<1,x);
	}
	
	else{
		if(x<=tr[u<<1|1].l+tr[u<<1|1].lmax-1)
		 return tr[u<<1|1].lmax + tr[u<<1].rmax;
		
		return query(u<<1|1,x);
	}
	
	
	
}



int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	while(cin>>n>>m){
		build(1,1,n);
		//cout<st;
		while(m--){
			cin>>c;
			if(c=='D'){cin>>x;modify(1,x,0);st.push(x);}
			else if(c=='R'){
				if(st.size()){
					int t = st.top();
					st.pop();
					modify(1,t,1);
				}
				
			}
			else {cin>>x;cout<

你可能感兴趣的:(线段树,数据结构,算法,c++)