标签: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