标签:ini lse make 前缀 while inf double -- size
题意:
一个$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; }
标签:ini lse make 前缀 while inf double -- size
原文地址:https://www.cnblogs.com/nervendnig/p/10203281.html