• 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 '
    '
    #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;
    }
    

      

  • 相关阅读:
    java垃圾回收算法和垃圾收集器
    (转)数据库ACID特性
    数据库范式
    (转)java Exception层次结构详解
    java Thread方法解析: sleep join wait notify notifyAll
    (转)java反编译i++和++i问题
    (转)git使用教程
    (转)java位运算
    (转)原码、反码、补码
    [翻译]如何编写GIMP插件(一)
  • 原文地址:https://www.cnblogs.com/nervendnig/p/10203281.html
Copyright © 2020-2023  润新知