[LCT] BZOJ 4817 [Sdoi2017]树点涂色
2017-05-03 21:33
489 查看
怎么萎事啊 sdoi怎么有这么多原题
看着这么眼熟
就是我们发现这个染色就是LCT上一个access的过程
而一个点到根路径的颜色数就是到根虚边数加1
这个我们可以access的时候顺便在线段树上子树修改下
而两个点之间的路径颜色数就是加一加再减去lca的两倍然后再加1 那个加1是指lca所属的颜色
子树最大值 直接线段树上查咯
看着这么眼熟
就是我们发现这个染色就是LCT上一个access的过程
而一个点到根路径的颜色数就是到根虚边数加1
这个我们可以access的时候顺便在线段树上子树修改下
而两个点之间的路径颜色数就是加一加再减去lca的两倍然后再加1 那个加1是指lca所属的颜色
子树最大值 直接线段树上查咯
#include<cstdio> #include<cstdlib> #include<stack> #include<algorithm> using namespace std; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } const int N=100005; const int K=18; struct edge{ int u,v,next; }G[N<<1]; int head ,inum; inline void add(int u,int v,int p){ G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p; } #define V G[p].v int size ,depth ,fat [K]; int pre ,clk,back ; inline void dfs(int u,int fa){ fat[u][0]=fa; depth[u]=depth[fa]+1; size[u]=1; pre[u]=++clk; back[clk]=u; for (int k=1;k<K;k++) fat[u][k]=fat[fat[u][k-1]][k-1]; for (int p=head[u];p;p=G[p].next) if (V!=fa) dfs(V,u),size[u]+=size[V]; } inline int LCA(int u,int v){ if (depth[u]<depth[v]) swap(u,v); for (int k=K-1;~k;k--) if ((depth[u]-depth[v])>>k&1) u=fat[u][k]; if (u==v) return u; for (int k=K-1;~k;k--) if (fat[u][k]!=fat[v][k]) u=fat[u][k],v=fat[v][k]; return fat[u][0]; } struct SEG{ int T[N<<2],F[N<<2]; inline void Build(int x,int l,int r){ if (l==r){ T[x]=depth[back[l]]-1; return; } int mid=(l+r)>>1; Build(x<<1,l,mid); Build(x<<1|1,mid+1,r); T[x]=max(T[x<<1],T[x<<1|1]); } inline void mark(int x,int t){ F[x]+=t; T[x]+=t; } inline void Add(int x,int l,int r,int ql,int qr,int t){ if (ql<=l && r<=qr){ mark(x,t); return; } if (F[x]) mark(x<<1,F[x]),mark(x<<1|1,F[x]),F[x]=0; int mid=(l+r)>>1; if (ql<=mid) Add(x<<1,l,mid,ql,qr,t); if (qr>mid) Add(x<<1|1,mid+1,r,ql,qr,t); T[x]=max(T[x<<1],T[x<<1|1]); } inline int Query(int x,int l,int r,int ql,int qr){ if (ql<=l && r<=qr) return T[x]; if (F[x]) mark(x<<1,F[x]),mark(x<<1|1,F[x]),F[x]=0; int mid=(l+r)>>1,ret=-1<<30; if (ql<=mid) ret=max(ret,Query(x<<1,l,mid,ql,qr)); if (qr>mid) ret=max(ret,Query(x<<1|1,mid+1,r,ql,qr)); return ret; } }Seg; int n; inline void Add(int x,int t){ Seg.Add(1,1,n,pre[x],pre[x]+size[x]-1,t); } inline int Query(int x){ return Seg.Query(1,1,n,pre[x],pre[x])+1; } struct node{ node *ch[2],*f; bool dir(){ return f->ch[1]==this; } bool isr(){ return !f || (f->ch[0]!=this && f->ch[1]!=this); } void setc(node *c,int d){ ch[d]=c; if (c) c->f=this; } //void push(){ } //void upd(){ } }pool ; inline void rot(node *x){ node *p=x->f; bool d=x->dir(); if (!p->isr()) p->f->setc(x,p->dir()); else x->f=p->f; p->setc(x->ch[d^1],d),x->setc(p,d^1);// p->upd(); } //stack<node*> sta; inline void splay(node *x){ //node *q=x; while (!q->isr()) sta.push(q),q=q->f; sta.push(q); //while (!sta.empty()) sta.top()->push(),sta.pop(); while (!x->isr()) if (x->f->isr()) rot(x); else if (x->dir()==x->f->dir()) rot(x->f),rot(x); else rot(x),rot(x); //x->upd(); } inline node *frt(node *x){ splay(x); for (;/*x->push(),*/x->ch[0];x=x->ch[0]); return x; } inline void expose(node *x){ for (node *q=NULL;x;q=x,x=x->f){ splay(x); node *ch=x->ch[1]; x->ch[1]=NULL; if (ch) Add(frt(ch)-pool,1); if (q) Add(frt(q)-pool,-1); x->ch[1]=q; //x->upd(); } } int main(){ int Q,order,iu,iv; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(Q); for (int i=1;i<n;i++) read(iu),read(iv),add(iu,iv,++inum),add(iv,iu,++inum); dfs(1,0); Seg.Build(1,1,n); for (int i=2;i<=n;i++) pool[i].f=pool+fat[i][0]; while (Q--){ read(order); read(iu); if (order==1){ expose(pool+iu); }else if (order==2){ read(iv); int lca=LCA(iu,iv); printf("%d\n",Query(iu)+Query(iv)-2*Query(lca)+1); }else{ printf("%d\n",Seg.Query(1,1,n,pre[iu],pre[iu]+size[iu]-1)+1); } } return 0; }
相关文章推荐
- BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树
- 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]
- [BZOJ4817][SDOI2017]树点涂色(DFS序+LCA+树剖+LCT)
- [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)
- [bzoj4817][Sdoi2017]树点涂色
- bzoj4817 [Sdoi2017]树点涂色
- [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)
- BZOJ4817 [Sdoi2017]树点涂色(洛谷P3703)
- Bzoj4817 [Sdoi2017]树点涂色
- [BZOJ4817][SDOI2017]树点涂色(LCT+线段树+差分)
- [BZOJ4817][SDOI2017]树点涂色
- bzoj4817 [Sdoi2017]树点涂色
- bzoj4817 [Sdoi2017]树点涂色
- 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
- [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]
- 【BZOJ4817】【SDOI2017】树点染色
- 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序
- 【bzoj4817】[Sdoi2017]树点涂色 LCT+LCA+线段树
- [LCT] BZOJ4817.[Sdoi2017]树点涂色
- BZOJ4817 [Sdoi2017]树点涂色