[BZOJ4573][UOJ#195][Zjoi2016][LCT][离线]大森林
2017-03-29 17:58
465 查看
http://blog.csdn.net/lych_cys/article/details/53515748#
神想法啊…
至于求两点间距离为什么不能直接把两点的链拉出来
可以考虑因为树上虚点,两个点的LCA可以是一个虚点,虚点的父节点才是它们真正的LCA,所以直接拉一条链会导致少算一个点,而算LCA的话不会有这个问题(可以脑补一下)
神想法啊…
至于求两点间距离为什么不能直接把两点的链拉出来
可以考虑因为树上虚点,两个点的LCA可以是一个虚点,虚点的父节点才是它们真正的LCA,所以直接拉一条链会导致少算一个点,而算LCA的话不会有这个问题(可以脑补一下)
#include <cstdio> #include <iostream> #include <algorithm> #include <string> #include <cstring> #include <vector> #define N 100010 using namespace std; int n,m,cnt,top,tot,g,cnt0; int Ans ,stc ,L ,R ; struct lef{ int Size,rev,key; lef *ch[2],*fa; int isr(){ return (!fa)||(fa->ch[0]!=this&&fa->ch[1]!=this); } int isl(){ return fa&&fa->ch[1]==this; } void Up(){ Size=key+(ch[0]?ch[0]->Size:0)+(ch[1]?ch[1]->Size:0); } void reverse(){ access(); splay(); rev^=1; } void Push(){ if(!rev) return ; swap(ch[0],ch[1]); if(ch[0]) ch[0]->rev^=1; if(ch[1]) ch[1]->rev^=1; rev=0; } lef *access(){ lef *t,*x,*p; for(t=0,x=this;x;x=x->fa) p=x,x->splay(),x->ch[1]=t,t=x,x->Up(); return p; } void splay(){ Pushtop(); for(lef *x=this;!x->isr();x->rot()) if(!x->fa->isr()) ((x->isl())^(x->fa->isl()))?x->rot():x->fa->rot(); } void rot(){ lef *x=this,*y=x->fa,*z=y->fa; int wh=x->isl(); if(!y->isr()) z->ch[z->ch[1]==y]=x; x->fa=z; if(y->ch[wh]=x->ch[wh^1]) y->ch[wh]->fa=y; x->ch[wh^1]=y; y->fa=x; y->Up(); x->Up(); } void Pushtop(){ if(!isr()) this->fa->Pushtop(); Push(); } }A[N<<2]; struct stp{int op,x,y,z,g;}; vector<stp> work ; inline void link(int x,int y){ A[x].reverse(); A[x].fa=&A[y]; A[x].access(); } inline void cut(int x,int y){ A[x].reverse(); A[y].access(); A[y].splay(); A[y].ch[0]=A[x].fa=0; A[y].Up(); } inline int query(int x,int y){ int ret=0; lef *lca; A[1].reverse(); A[x].access(); A[x].splay(); ret=A[x].Size; lca=A[y].access(); A[y].splay(); ret+=A[y].Size; lca->access(); lca->splay(); ret-=2*(lca->Size); return ret; } inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p2==p1)?EOF:*p1++; } inline void rea(int &x){ char c=nc(); x=0; for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc()); } inline lef *newd(int x,int y){ A[x].Size=y; A[x].ch[0]=A[x].ch[1]=A[x].fa=0; A[x].key=y; return &A[x]; } int main(){ rea(n); rea(m); newd(cnt=1,1); L[cnt]=1; R[cnt]=n; newd(tot=m+1,0); link(tot,cnt); for(int i=1;i<=m;i++){ int op; rea(op); if(op==0){ ++cnt; rea(L[cnt]); rea(R[cnt]); newd(cnt,1); link(cnt,tot); } else if(op==1){ int l,r,x; rea(l); rea(r); rea(x); l=max(l,L[x]); r=min(r,R[x]); if(l<=r){ newd(++tot,0); link(tot,tot-1); work[l].push_back((stp){1,tot,tot-1,x}); work[r+1].push_back((stp){1,tot,x,tot-1}); } } else{ int x,y,z; rea(x); rea(y); rea(z); work[x].push_back((stp){2,x,y,z,++cnt0}); } } for(int i=1;i<=n;i++){ stp now; for(int j=0;j<work[i].size();j++){ now=work[i][j]; if(now.op==1){ cut(now.x,now.y); link(now.x,now.z); } else Ans[now.g]=query(now.y,now.z); } } for(int i=1;i<=cnt0;i++) printf("%d\n",Ans[i]); return 0; }
相关文章推荐
- [BZOJ4573][[Zjoi2016]大森林][LCT建虚点]
- [bzoj4573][UOJ#195][ZJOI2016]大森林
- bzoj 4573: [Zjoi2016]大森林 lct
- [BZOJ4573][ZJOI2016]大森林(LCT建虚点)
- [LCT || splay维护括号序列] BZOJ 4573 [Zjoi2016]大森林
- BZOJ4573 : [Zjoi2016]大森林
- Bzoj4573: [Zjoi2016]大森林
- bzoj 4573: [Zjoi2016]大森林
- BZOJ4573:[ZJOI2016]大森林——题解
- [带有虚点的LCT] BZOJ 4573: 大森林
- [BZOJ4573][ZJOI2016]大♂森林
- 洛谷P3348 [ZJOI2016]大森林(LCT,虚点,树上差分)
- [DP] BZOJ 4574 [Zjoi2016]线段树
- UOJ#267 BZOJ4731【清华集训2016】魔法小程序
- bzoj 4455: [Zjoi2016]小星星
- [BZOJ4455][Zjoi2016]小星星(容斥原理+树形DP)
- 【BZOJ 4455】 [Zjoi2016]小星星 容斥计数
- [bzoj2816][ZJOI2012]网络(LCT,splay)
- bzoj1036 [ZJOI2008]树的统计(树链剖分/lct)
- BZOJ 4455: [Zjoi2016]小星星