lct模板

from popoqqq 指针版
BZOJ 2049洞穴勘测

#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
    node *fa,*lc,*rc;
    bool rev;
    node();
    void pushdown();
}*null=new node,tree[10010];
node::node()
{
    fa=lc=rc=null;
}
void node::pushdown()
{
    if(fa->lc==this||fa->rc==this)
        fa->pushdown();
    if(rev)
    {
        lc->rev^=1;
        rc->rev^=1;
        swap(lc,rc);
        rev=0;
    }
}
void zig(node*x)
{
    node*y=x->fa,*z=y->fa;
    y->lc=x->rc;
    x->rc->fa=y;
    x->rc=y;
    y->fa=x;
    if(z->lc==y)z->lc=x;
    else if(z->rc==y)z->rc=x;
    x->fa=z;
}
void zag(node*x)
{
    node*y=x->fa,*z=y->fa;
    y->rc=x->lc;
    x->lc->fa=y;
    x->lc=y;
    y->fa=x;
    if(z->lc==y)z->lc=x;
    else if(z->rc==y)z->rc=x;
    x->fa=z;
}
void splay(node*x)
{
    x->pushdown();
    while(x->fa->lc==x||x->fa->rc==x)
    {
        node*y=x->fa,*z=y->fa;
        if(x==y->lc)
        {
            if(y==z->lc)zig(y);
            zig(x);
        }
        else
        {
            if(y==z->rc)zag(y);
            zag(x);
        }
    }
}
void access(node*x)
{
    node*y=null;
    while(x!=null)
    {
        splay(x);
        x->rc=y;
        y=x;
        x=x->fa;
    }
}
void toroot(node*x)
{
    access(x);
    splay(x);
    x->rev^=1;
    x->pushdown();
}
void query(node*x,node*y)
{
    access(x);
    splay(x);
    while(y->fa!=null)
        y=y->fa;
    if(y==x)puts("Yes");
    else puts("No");
}
void link(node*x,node*y)
{
    toroot(x);
    x->fa=y;
}
void cut(node*x,node*y)
{
    toroot(x);
    access(y);
    splay(y);
    y->lc=null;
    x->fa=null;
}
int n,m;
char op[7];
int main()
{
    null->fa=null->lc=null->rc=null;
    scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<=m;++i)
    {
        scanf("%s%d%d",op,&x,&y);
        if(op[0]=='Q')query(&tree[x],&tree[y]);
        else if(op[0]=='C')link(&tree[x],&tree[y]);
        else cut(&tree[x],&tree[y]);
    }
}

数组版(更简单)
SPOJ GSS7 Can you answer these queries VII

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,cnt,fa[100010],ch[100010][2],key[100010],lx[100010],rx[100010],mx[100010],sum[100010],sz[100010];
bool rt[100010],tag[100010],rev[100010];
void pushup(int x)
{
    int l=ch[x][0],r=ch[x][1];
    sz[x]=sz[l]+sz[r]+1;
    sum[x]=sum[l]+sum[r]+key[x];
    lx[x]=max(0,max(lx[l],sum[l]+key[x]+lx[r]));
    rx[x]=max(0,max(rx[r],sum[r]+key[x]+rx[l]));
    mx[x]=max(0,max(max(mx[l],mx[r]),max(0,rx[l])+key[x]+max(0,lx[r])));
}
void setv(int x,int w)
{
    if(x==0)return;
    key[x]=w;
    sum[x]=sz[x]*w;
    mx[x]=lx[x]=rx[x]=max(0,sum[x]);
    tag[x]=1;
}
void reverse(int x)
{
    swap(ch[x][0],ch[x][1]);
    swap(lx[x],rx[x]);
    rev[x]^=1;
}
void pushdown(int x)
{
    if(!rt[x])pushdown(fa[x]);
    if(tag[x])
    {
        setv(ch[x][0],key[x]);
        setv(ch[x][1],key[x]);
        tag[x]=0;
    }
    if(rev[x])
    {
        reverse(ch[x][0]);
        reverse(ch[x][1]);
        rev[x]=0;
    }
}
void rotate(int x)
{
    int y=fa[x],z=fa[y];
    bool f=ch[y][1]==x;
    ch[y][f]=ch[x][!f];
    fa[ch[y][f]]=y;
    ch[x][!f]=y;
    fa[ch[x][!f]]=x;
    fa[x]=z;
    if(rt[y])rt[y]=0,rt[x]=1;
    else ch[z][y==ch[z][1]]=x;
    pushup(y);
}
void splay(int x)
{
    pushdown(x);
    for(int y,z;!rt[x];rotate(x))
    {
        y=fa[x],z=fa[y];
        if(!rt[y])
        {
            if((ch[y][0]==x)^(ch[z][0]==y))rotate(x);
            else rotate(y);
        }
    }
    pushup(x);
}
void access(int x)
{
    for(int y=0;x;y=x,x=fa[x])
    {
        splay(x);
        rt[ch[x][1]]=1;
        ch[x][1]=y;
        rt[ch[x][1]]=0;
        pushup(x);
    }
}
void toroot(int x)
{
    access(x);
    splay(x);
    reverse(x);
}
void link(int x,int y)
{
    toroot(x);
    fa[x]=y;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&key[i]);
        sum[i]=key[i];
        sz[i]=1;
        lx[i]=rx[i]=mx[i]=max(0,key[i]);
        rt[i]=1;
    }
    for(int i=1,u,v;i<n;++i)
    {
        scanf("%d%d",&u,&v);
        link(u,v);
    }
    scanf("%d",&m);
    for(int i=1,op,u,v,c;i<=m;++i)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d",&u,&v);
            toroot(u);
            access(v);
            splay(v);
            printf("%d\n",mx[v]);
        }
        else
        {
            scanf("%d%d%d",&u,&v,&c);
            toroot(u);
            access(v);
            splay(v);
            setv(v,c);
            pushdown(v);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值