您的位置:首页 > 其它

bzoj4530 [Bjoi2014]大融合

2018-01-03 11:47 211 查看
LCT维护子树size

具体维护子树信息请看我的少女

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#define N 100005
using namespace std;
struct Node{
Node *ch[2],*fa;
int sum,sxu,rev,id;
Node ();
void Rev();
void pushup();
void pushdown();
}*null=new Node,tree
;
Node :: Node(){
ch[0]=ch[1]=fa=null;
sum=1;sxu=rev=id=0;
}
void Node :: Rev(){
rev^=1;
swap(ch[0],ch[1]);
}
void Node :: pushup(){
sum=ch[0]->sum+ch[1]->sum+sxu+1;
}
void Node :: pushdown(){
if(rev){
ch[0]->Rev();
ch[1]->Rev();
rev=0;
}
}
void rotate(Node *x){
Node *y=x->fa,*z=y->fa;
int w=y->ch[1]==x;
y->ch[w]=x->ch[w^1];x->ch[w^1]->fa=y;
x->ch[w^1]=y;y->fa=x;
if(z->ch[0]==y)z->ch[0]=x;
if(z->ch[1]==y)z->ch[1]=x;
x->fa=z;
y->pushup();x->pushup();
}
bool isroot(Node *x){
return (x->fa->ch[0]!=x)&&(x->fa->ch[1]!=x);
}
void splay(Node *x){
Node *y,*z;
x->pushdown();
while(!isroot(x)){
y=x->fa;z=y->fa;
z->pushdown();y->pushdown();x->pushdown();
if((z->ch[0]==y&&y->ch[0]==x)||(z->ch[1]==y&&y->ch[1]==x))
rotate(y);
rotate(x);
}
}
void access(Node *x){
Node *y=null;
while(x!=null){
splay(x);
x->sxu+=x->ch[1]->sum-y->sum;
x->ch[1]=y;
x->pushup();
y=x;x=x->fa;
}
}
void make_root(Node *x){
access(x);
splay(x);
x->Rev();
}
void link(Node *x,Node *y){
make_root(x);
make_root(y);
x->fa=y;
y->sxu+=x->sum;
y->pushup();
}
long long query(Node *x,Node *y){
make_root(x);
make_root(y);
return 1ll*((y->sum)-(x->sum))*(x->sum);
}
int n,m;
int main(){
null->ch[0]=null->ch[1]=null->fa=null;
null->sum=null->sxu=null->rev=null->id=0;
scanf("%d%d",&n,&m);
char ch[2];
int x,y;
for(int i=1;i<=n;i++)
tree[i].id=i;
while(m--){
scanf("%s%d%d",ch,&x,&y);
if(ch[0]=='A') link(&tree[x],&tree[y]);
else printf("%lld\n",query(&tree[x],&tree[y]));
}
}
/*
10 1000
A 1 2
A 1 5
Q 1 2
A 2 3
Q 1 2
Q 1 5
A 5 6
A 5 7
Q 1 5
Q 2 3
A 3 4
A 4 8
A 8 9
A 9 10
Q 3 4
Q 4 8
Q 8 9
Q 9 10
*/


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: