hdu 1540 Tunnel Warfare 线段树

题意:

一个$01$串,一开始全为$1$,

$3$种操作:

  $D x$ 把$a_x$修改为$0$

  $Q x$ 询问包含位置$x$的最长$1$串的长度

  $R $ 撤销最近一次的$D x$操作

题解:
线段树

每个节点维护$3$个区间信息

最长的连续$1$,.最长的前缀$1$,最长的后缀$1$

然后进行单点修改,区间求值即可

(写这个博客的原因是这次我把线段树放在一个struct里面了)

#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define mp make_pair
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define IO ios::sync_with_stdio(false)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(int ii=b;ii>=a;--ii)
#define forn(ii,x) for(int ii=head[x];ii;ii=e[ii].next)
using namespace std;
const int maxn=1e5+10,maxm=2e6+10;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const double PI=acos(-1.0);
//head
int casn,n,m,k;
struct segnode {
	int l,r,ls,rs,ms;
	int mid(){return (r+l)>>1;}
	int len(){return r-l+1;}
};
struct segtree{
#define nd  seg[now]
#define ndl seg[now<<1]
#define ndr seg[now<<1|1]
	segnode seg[maxn<<2];
	int mxsize;
	void init(int n){mxsize=n;maketree(1,n);}
	void pushup(int now){
		nd.ls=ndl.ls,nd.rs=ndr.rs;
		nd.ms=max(ndl.rs+ndr.ls,max(ndl.ms,ndr.ms));
		if(ndl.ms==ndl.len()) nd.ls+=ndr.ls;
		if(ndr.ms==ndr.len()) nd.rs+=ndl.rs;
	}
	void pushdown(){return;}
	void maketree(int s,int t,int now=1){
		nd={s,t,t-s+1,t-s+1,t-s+1};
		if(s==t)return ;
		maketree(s,(s+t)>>1,now<<1);
		maketree(((s+t)>>1)+1,t,now<<1|1);
	}
	void update(int pos,int x,int now=1){
		if(nd.len()==1){
			nd.ms=nd.rs=nd.ls=x;
			return ;
		}
		if(pos<=nd.mid()) update(pos,x,now<<1);
		else update(pos,x,now<<1|1);
		pushup(now);
	}
	int query(int pos,int now=1){
		if(nd.len()==1||nd.ms==0||nd.ms==nd.len())return nd.ms;
		if(pos<=nd.mid()){
			if(pos>=ndl.r-ndl.rs+1)
				return query(pos,now<<1)+query(nd.mid()+1,now<<1|1);
			else return query(pos,now<<1);
		}else {
			if(pos<=ndr.l+ndr.ls-1)
				return query(pos,now<<1|1)+query(nd.mid(),now<<1);
			else return query(pos,now<<1|1);
		}
	}
}tree;
int main() {
	IO;
	string s;int t;
	while(cin>>n>>m){
		tree.init(n);
		stack<int> stk;
		while(m--){
			cin>>s;
			if(s[0]=='D'){
				cin>>t;
				stk.push(t);
				tree.update(t,0);
			}else if(s[0]=='Q'){
				cin>>t;
				cout<<tree.query(t)<<endl;
			}else if(!stk.empty()){
				tree.update(stk.top(),1);
				stk.pop();
			}
		}
	}
	return 0;
}

  

posted @ 2018-12-31 20:57  nervending  阅读(205)  评论(0编辑  收藏  举报