首页 > 其他 > 详细

BZOJ4530 [BJOI2014] 大融合

时间:2019-09-26 13:25:25      阅读:106      评论:0      收藏:0      [点我收藏+]

LCT维护子树信息(

考虑维护两个值,一个虚子树信息,一个全部信息。

因为虚子树只有在link和access的时候改变,可以方便的维护。

具体可以康康代码。

近期考虑写点大代码题练练手。

技术分享图片
//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
#define fa(x) t[x].fa
#define ls(x) t[x].son[0]
#define rs(x) t[x].son[1]
#define nrt(x) (ls(fa(x))==x||rs(fa(x))==x)
#define N 100010
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<0||ch>9){if(ch==-) f=-1; ch=getchar();}
    while(ch>=0&&ch<=9) s=s*10+ch-0,ch=getchar();
    return f*s;
}
struct node{int cnt,sum,fa,son[2]; bool tag;}t[N];
void pushup(int x){t[x].sum=1+t[x].cnt+t[ls(x)].sum+t[rs(x)].sum;}
void rotate(int x)
{
    if(!nrt(x) || !x)    return;
    int f=fa(x),gf=fa(f);
    int k=rs(f)==x,p=k^1;
    if(nrt(f))    t[gf].son[rs(gf)==f]=x;
    if(t[x].son[p])    t[t[x].son[p]].fa=f;
    t[f].son[k]=t[x].son[p]; t[x].son[p]=f;
    t[x].fa=gf; t[f].fa=x;
    pushup(f); pushup(x);
}
void pushdown(int x)
{
    if(t[x].tag)
    {
        swap(ls(x),rs(x));
        if(ls(x))    t[ls(x)].tag^=1;
        if(rs(x))    t[rs(x)].tag^=1;
        t[x].tag=0;
    }
}
void push(int x)
{
    if(nrt(x))    push(fa(x));
    pushdown(x);
}
void splay(int x)
{
    push(x);
    while(nrt(x))
    {
        int f=fa(x),gf=fa(f);
        if(nrt(gf))    (rs(f)==x)^(rs(gf)==f)?rotate(x):rotate(f);
        rotate(x);
    }
}
void access(int x)
{
    int y=0;
    do
    {
        splay(x); t[x].cnt+=t[rs(x)].sum-t[y].sum;
        rs(x)=y; pushup(x); y=x; x=fa(x);
    }while(x);
}
void makeroot(int x)
{
    access(x); splay(x); t[x].tag=1;
}
int getroot(int x)
{
    access(x); splay(x);
    while(ls(x))    x=ls(x);
    return x;
}
void split(int x,int y)
{
    makeroot(x); access(y); splay(y);
}
void link(int x,int y)
{
    split(x,y);
    if(getroot(y)==x)    return;
    t[x].fa=y; t[y].cnt+=t[x].sum;
}
ll calc(int x,int y)
{
    split(x,y);
    return 1ll*t[x].sum*(t[y].sum-t[x].sum);
}
char ch[10];
int main()
{
    int n=read(),m=read();
    for(int i=1;i<=n;i++)    t[i].sum=1;
    while(m--)
    {
        scanf("%s",ch); int x=read(),y=read();
        if(ch[0]==A)    link(x,y);
        else    printf("%lld\n",calc(x,y));
    }
    return 0;
}
View Code

 

BZOJ4530 [BJOI2014] 大融合

原文:https://www.cnblogs.com/hanyuweining/p/11589666.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!