bzoj 4530: [Bjoi2014]大融合 lct维护子树信息
2017-07-11 10:05
531 查看
题意
给你n个点,要求资瓷以下操作:A x y连接x和y。
Q x y询问x所在的树上有多少条简单路径经过x到y这条边。
n,m<=100000
分析
lct维护子树信息这题显然是要动态维护每个点的size。
考虑如何用lct维护子树大小。
定义siz[x]表示x的所有虚儿子的子树大小和,size[x]表示x的所有虚儿子+实儿子+自己的子树大小和。那么只要在虚实边变化的时候维护一下siz的大小,同时维护size就好了。
求x的子树大小,只要access(x),然后siz[x]+1就是答案了。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<stack> using namespace std; typedef long long LL; const int N=100005; int n,m; struct tree{int siz,size,l,r,fa,rev;}t ; stack<int> sta; int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } bool is_root(int x) { return !t[x].fa||(x!=t[t[x].fa].l&&x!=t[t[x].fa].r); } void updata(int x) { t[x].size=t[t[x].l].size+t[t[x].r].size+t[x].siz+1; } void pushdown(int x) { if (!t[x].rev) return; t[x].rev^=1;swap(t[x].l,t[x].r); if (t[x].l) t[t[x].l].rev^=1; if (t[x].r) t[t[x].r].rev^=1; } void rttr(int x) { int y=t[x].l; t[x].l=t[y].r;t[t[y].r].fa=x; if (x==t[t[x].fa].l) t[t[x].fa].l=y; else if (x==t[t[x].fa].r) t[t[x].fa].r=y; t[y].fa=t[x].fa; t[y].r=x;t[x].fa=y; updata(x);updata(y); } void rttl(int x) { int y=t[x].r; t[x].r=t[y].l;t[t[y].l].fa=x; if (x==t[t[x].fa].l) t[t[x].fa].l=y; else if (x==t[t[x].fa].r) t[t[x].fa].r=y; t[y].fa=t[x].fa; t[y].l=x;t[x].fa=y; updata(x);updata(y); } void remove(int x) { while (!is_root(x)) sta.push(x),x=t[x].fa; pushdown(x); while (!sta.empty()) x=sta.top(),sta.pop(),pushdown(x); } void splay(int x) { remove(x); while (!is_root(x)) { int p=t[x].fa,g=t[p].fa; if (is_root(p)) { if (x==t[p].l) rttr(p); else rttl(p); break; } if (x==t[p].l) if (p==t[g].l) rttr(g),rttr(p); else rttr(p),rttl(g); else if (p==t[g].r) rttl(g),rttl(p); else rttl(p),rttr(g); } } void access(int x) { int p=0; while (x) { splay(x); t[x].siz+=t[t[x].r].size; t[x].r=p; t[x].siz-=t[p].size; updata(x); p=x;x=t[x].fa; } } void make_root(int x) { access(x);splay(x);t[x].rev^=1; } void link(int x,int y) { make_root(x);make_root(y);t[x].fa=y;t[y].siz+=t[x].size;updata(y); } int main() { n=read();m=read(); for (int i=1;i<=n;i++) t[i].size=1; while (m--) { char ch[2]; scanf("%s",ch); int x=read(),y=read(); if (ch[0]=='A') link(x,y); else { make_root(x);access(y);splay(x); printf("%lld\n",(LL)(t[y].siz+1)*(t[x].size-t[y].siz-1)); } } return 0; }
相关文章推荐
- BZOJ 4530 [Bjoi2014]大融合 LCT维护子树信息
- [BZOJ4530][Bjoi2014][LCT维护子树信息]大融合
- 【bzoj4530】[Bjoi2014]大融合 LCT维护子树信息
- 【BZOJ4530】[Bjoi2014]大融合 LCT维护子树信息
- BZOJ4530 BJOI 2014 大融合 LCT维护子树信息
- BZOJ 4530: [Bjoi2014]大融合 lct维护子树信息
- [BZOJ]4530 [BJOI2014] 大融合 LCT维护子树信息
- 【LCT维护子树信息】BZOJ4530(Bjoi2014)[大融合]题解
- bzoj4530 [Bjoi2014]大融合(LCT维护子树大小)
- [BZOJ4530]-大融合-LCT维护子树信息
- 【bzoj 4530】大融合(LCT维护子树信息)
- LCT维护子树信息(BZOJ4530:[BJOI2014]大融合)
- bzoj4530 [Bjoi2014]大融合 (LCT维护子树信息)
- BZOJ.4530.[BJOI2014]大融合(LCT)
- BZOJ 4530 [Bjoi2014]大融合 [LCT]
- bzoj4530 [Bjoi2014]大融合(lct维护虚边信息)
- 【bzoj4530】大融合(LCT的子树维护)
- JZOJ 3766【BJOI2014】大融合(lct维护子树大小)
- BZOJ_4530_[Bjoi2014]大融合_LCT
- [bzoj4530][Bjoi2014]大融合_LCT