太神辣太神辣太神辣
炒鸡线段树神题
膜岛娘OrzOrzOrz题解
#include<iostream> #include<cstdio> #include<cstring> #define lc o<<1 #define rc o<<1|1 using namespace std; const int inf=1e9; struct Node{ int l,r,a,b,rp,rm,lp,lm,dis; }tr[1200005]; int tp[300005],black; //0 黑点 1左括号 2右括号 inline void pushup(int o){ int a=tr[lc].a,b=tr[lc].b,c=tr[rc].a,d=tr[rc].b; if(b<c){ tr[o].a=a+c-b; tr[o].b=d; }else{ tr[o].a=a; tr[o].b=b+d-c; } tr[o].dis=max(max(tr[lc].dis,tr[rc].dis),max(tr[lc].rp+tr[rc].lm,tr[lc].rm+tr[rc].lp)); tr[o].rp=max(tr[rc].rp,max(tr[lc].rp-c+d,tr[lc].rm+c+d)); tr[o].rm=max(tr[lc].rm+c-d,tr[rc].rm); tr[o].lp=max(tr[lc].lp,max(tr[rc].lp-b+a,tr[rc].lm+a+b)); tr[o].lm=max(tr[rc].lm+b-a,tr[lc].lm); } void build(int o,int l,int r){ tr[o].l=l;tr[o].r=r; if(l==r){ tr[o].dis=-inf; if(tp[l])tr[o].rp=tr[o].rm=tr[o].lp=tr[o].lm=-inf; if(tp[l]==1)tr[o].b=1; if(tp[l]==2)tr[o].a=1; return; } int m=l+r>>1; build(lc,l,m);build(rc,m+1,r); pushup(o); } void update(int o,int p){ int l=tr[o].l,r=tr[o].r; if(l==r){ if(!tr[o].lp){ black--; tr[o].lp=tr[o].lm=tr[o].rp=tr[o].rm=-inf; }else{ black++; tr[o].lp=tr[o].lm=tr[o].rp=tr[o].rm=0; } }else{ int m=l+r>>1; if(p<=m)update(lc,p); else update(rc,p); pushup(o); } } struct Edge{int to,next;}e[200005]; int head[100005],cnt,pos[100005],sz; void ins(int u,int v){ cnt++;e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt; } void dfs(int u,int fa){ tp[++sz]=1;pos[u]=++sz; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(v==fa)continue; dfs(v,u); } tp[++sz]=2; } int main(){ int n;scanf("%d",&n); int u,v; for(int i=1;i<n;i++){ scanf("%d%d",&u,&v); ins(u,v);ins(v,u); } dfs(1,0);build(1,1,3*n); int q;scanf("%d",&q); char opt[10]; black=n; while(q--){ scanf("%s",opt); if(opt[0]=='C'){ scanf("%d",&u); update(1,pos[u]); }else{ if(black==0)puts("-1"); else if(black==1)puts("0"); else printf("%d\n",tr[1].dis); } } return 0; }