题意:给定n个排成一行的村庄(编号从1到n)和m次操作。
D x 表示破坏x村庄,Q x 表示查询x村庄所能联络的村庄数,R 表示重建最后一个被破坏的村庄,求单点所在连续村庄的最大长度
思路:分为两种情况:(1).区间内的连续长度 (2). 左区间右连续+右区间左连续
#include <bits/stdc++.h> using namespace std; #define mst(a,b) memset((a),(b),sizeof(a)) #define f(i,a,b) for(int i=(a);i<=(b);++i) const int maxn =50005; const int mod = 1e9+7; const int INF = 1e9; //#define m ((l+r)>>1) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define ll long long #define rush() int T;scanf("%d",&T);while(T--) struct node { int l,r,len; int lsum,rsum,sum; }tree[maxn<<2]; void pushup(int rt) { tree[rt].lsum=tree[rt<<1].lsum; tree[rt].rsum=tree[rt<<1|1].rsum; tree[rt].sum=max(tree[rt<<1].sum,tree[rt<<1|1].sum); tree[rt].sum=max(tree[rt].sum,tree[rt<<1|1].lsum+tree[rt<<1].rsum); if(tree[rt].lsum==tree[rt<<1].len) { tree[rt].lsum+=tree[rt<<1|1].lsum; } if(tree[rt].rsum==tree[rt<<1|1].len) { tree[rt].rsum+=tree[rt<<1].rsum; } } void build(int l,int r,int rt) { tree[rt].l=l; tree[rt].r=r; tree[rt].len=tree[rt].lsum=tree[rt].rsum=tree[rt].sum=r-l+1; if(l==r) { return; } int m=(l+r)>>1; build(lson); build(rson); } void update(int pos,int n,int rt) { if(tree[rt].l==tree[rt].r) { tree[rt].lsum=tree[rt].rsum=tree[rt].sum=n; return; } int m=(tree[rt].l+tree[rt].r)>>1; if(pos<=m) update(pos,n,rt<<1); else update(pos,n,rt<<1|1); pushup(rt); } int query(int pos,int rt) { if(tree[rt].l==tree[rt].r) return tree[rt].sum; int m=(tree[rt].l+tree[rt].r)>>1; if(pos<=m) { int ans1=query(pos,rt<<1),ans2=0; if(pos>=tree[rt<<1].r-tree[rt<<1].rsum+1) ans2=tree[rt<<1].rsum+tree[rt<<1|1].lsum; return max(ans1,ans2); } else { int ans1=query(pos,rt<<1|1),ans2=0; if(pos<=tree[rt<<1|1].l+tree[rt<<1|1].lsum-1) ans2=tree[rt<<1].rsum+tree[rt<<1|1].lsum; return max(ans1,ans2); } } int main() { int n,m,x; char str[2]; while(~scanf("%d%d",&n,&m)) { build(1,n,1); stack<int>s; while(m--) { scanf("%s",str); if(str[0]=='R') { if(s.size()) { x=s.top(); s.pop(); update(x,1,1); } } else { scanf("%d",&x); if(str[0]=='D') { update(x,0,1); s.push(x); } else if(str[0]=='Q') { int ans=query(x,1); printf("%d\n",ans); } } } } return 0; }
(if判断语句尾加了个分号,导致错误,查错查了一个多小时,引以为戒。。。)