P3968 [TJOI2014]电源插排
线段树维护最长空区间及左端点位置,这个和$nlongn$的动态最大子序和差不多,就不多解释了
$n$较大哈希优化空间
My complete code:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> using namespace std; typedef long long LL; const LL maxn=3000000; const LL hs=299987; inline LL Read(){ LL x=0,f=1; char c=getchar(); while(c<'0'||c>'9'){ if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9'){ x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }return x*f; } struct node{ LL son[2],lx,rx,mx,mxi,col; }tree[maxn]; LL n,q,nod=1,root=1; LL que[300000][2]; inline LL Get(LL x){ LL u=x%hs+1; while(que[u][0]&&que[u][0]!=x) u=(u+1)%n; return u; } inline void Update(node &now,node son0,node son1,LL l,LL r,LL mid){ if(!son0.col) son0.lx=son0.rx=son0.mx=(mid-l+1); if(!son1.col) son1.lx=son1.rx=son1.mx=(r-mid); if(son0.mx>son1.mx) now.mx=son0.mx,now.mxi=son0.mxi; else now.mx=son1.mx,now.mxi=son1.mxi; if(son0.rx+son1.lx>now.mx||(son0.rx+son1.lx==now.mx&&mid-son0.rx+1>now.mxi)) now.mx=son0.rx+son1.lx, now.mxi=mid-son0.rx+1; now.lx=son0.lx,now.rx=son1.rx; if(!son0.col) now.lx+=son1.lx; if(!son1.col) now.rx+=son0.rx; now.col=son0.col+son1.col; } void Change(LL &now,LL l,LL r,LL x,LL c){ if(!now) now=++nod; if(l==r){ tree[now].col=c; tree[now].lx=tree[now].rx=tree[now].mx=!c; if(!c) tree[now].mxi=l; return; } LL mid=(l+r)>>1; x<=mid?Change(tree[now].son[0],l,mid,x,c):Change(tree[now].son[1],mid+1,r,x,c); Update(tree[now],tree[tree[now].son[0]],tree[tree[now].son[1]],l,r,mid); } LL Query(LL now,LL l,LL r,LL lt,LL rt){ if(!now) return 0; if(lt<=l&&rt>=r) return tree[now].col; LL mid=(l+r)>>1; LL sum=0; if(lt<=mid) sum+=Query(tree[now].son[0],l,mid,lt,rt); if(rt>mid) sum+=Query(tree[now].son[1],mid+1,r,lt,rt); return sum; } int main(){ n=Read(),q=Read(); tree[root].mx=n, tree[root].mxi=1; while(q--){ LL op=Read(); if(!op){ LL l=Read(),r=Read(); printf("%lld\n",Query(root,1,n,l,r)); }else{ LL x=Get(op); if(que[x][1]){ Change(root,1,n,que[x][1],0); que[x][1]=0; }else{ que[x][0]=op; LL now=(tree[1].mxi*2+tree[1].mx)>>1; Change(root,1,n,now,1); que[x][1]=now; } } } return 0; }