BZOJ 2631 tree

Posted on 2017-04-05 14:56  ziliuziliu  阅读(121)  评论(0编辑  收藏  举报

LCT?不存在的!

。。。。

注意此处kr=val,val=sum。pushdown的时候把这些东西一起更新了会方便很多。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 100050
#define mod 51061
#define int unsigned
using namespace std;
int n,q,u,v,c,tree[maxv][3],rev[maxv],val[maxv],kr[maxv];
int tag1[maxv],tag2[maxv],fath[maxv],st[maxv],top=0,size[maxv];
char s[4];
int read()
{
    int ch=getchar(),data=0;
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9')
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data;
}
bool isroot(int x) {return tree[fath[x]][1]!=x && tree[fath[x]][2]!=x;}
void pushup(int x) {val[x]=(val[tree[x][1]]+val[tree[x][2]]+kr[x])%mod;size[x]=size[tree[x][1]]+size[tree[x][2]]+1;}
void pushdown(int x)
{
    if (rev[x]) {swap(tree[x][1],tree[x][2]);rev[tree[x][1]]^=1;rev[tree[x][2]]^=1;rev[x]=0;}
    if (tag2[x]-1)
    {
        kr[tree[x][1]]*=tag2[x];kr[tree[x][1]]%=mod;tag1[tree[x][1]]*=tag2[x];tag1[tree[x][1]]%=mod;
        kr[tree[x][2]]*=tag2[x];kr[tree[x][2]]%=mod;tag1[tree[x][2]]*=tag2[x];tag1[tree[x][2]]%=mod;
        tag2[tree[x][1]]*=tag2[x];tag2[tree[x][1]]%=mod;tag2[tree[x][2]]*=tag2[x];tag2[tree[x][2]]%=mod;
        val[tree[x][1]]*=tag2[x];val[tree[x][1]]%=mod;val[tree[x][2]]*=tag2[x];val[tree[x][2]]%=mod;
        tag2[x]=1;
    }
    if (tag1[x])
    {
        kr[tree[x][1]]+=tag1[x];kr[tree[x][1]]%=mod;tag1[tree[x][1]]+=tag1[x];tag1[tree[x][1]]%=mod;
        kr[tree[x][2]]+=tag1[x];kr[tree[x][2]]%=mod;tag1[tree[x][2]]+=tag1[x];tag1[tree[x][2]]%=mod;
        val[tree[x][1]]+=size[tree[x][1]]*tag1[x]%mod;val[tree[x][1]]%=mod;
        val[tree[x][2]]+=size[tree[x][2]]*tag1[x]%mod;val[tree[x][2]]%=mod;
        tag1[x]=0;
    }
}
void rotate(int x)
{
    int y=fath[x],z=fath[y],l,r;
    if (tree[y][1]==x) l=1;else l=2;r=3-l;
    if (!isroot(y))
    {
        if (tree[z][1]==y) tree[z][1]=x;
        else tree[z][2]=x;
    }
    fath[x]=z;fath[y]=x;fath[tree[x][r]]=y;
    tree[y][l]=tree[x][r];tree[x][r]=y;
    pushup(y);pushup(x);
}
void splay(int x)
{
    int t=x;top=0;
    while (!isroot(t)) {st[++top]=t;t=fath[t];}st[++top]=t;
    for (int i=top;i>=1;i--) pushdown(st[i]);
    while (!isroot(x))
    {
        int y=fath[x],z=fath[y];
        if (!isroot(y))
        {
            if ((tree[z][1]==y)^(tree[y][1]==x)) rotate(x);
            else rotate(y);
        }
        rotate(x);
    }
}
void access(int x)
{
    int regis=0;
    while (x)
    {
        splay(x);
        tree[x][2]=regis;
        regis=x;pushup(x);
        x=fath[x];
    }
}
void makeroot(int x) {access(x);splay(x);rev[x]^=1;}
void cut(int u,int v) {makeroot(u);access(v);splay(v);tree[v][1]=fath[u]=0;}
void link(int u,int v) {makeroot(u);fath[u]=v;splay(u);}
void modify(int u,int v,int c,int type)
{
    makeroot(u);
    access(v);
    splay(v);
    if (type==1) {tag1[v]+=c;tag1[v]%=mod;kr[v]+=c;kr[v]%=mod;pushup(v);}
    else {tag1[v]*=c;tag1[v]%=mod;tag2[v]*=c;tag2[v]%=mod;kr[v]*=c;kr[v]%=mod;pushup(v);}
}
int ask(int u,int v)
{
    makeroot(u);
    access(v);
    splay(v);
    return val[v]%mod;
}
main()
{
    n=read();q=read();
    for (int i=1;i<=n;i++) val[i]=tag2[i]=kr[i]=1;
    for (int i=1;i<=n-1;i++)
    {
        u=read();v=read();
        link(u,v);
    }
    for (int i=1;i<=q;i++)
    {
        scanf("%s",s);
        if (s[0]=='+') {u=read();v=read();c=read();modify(u,v,c,1);}
        else if (s[0]=='*') {u=read();v=read();c=read();modify(u,v,c,2);}
        else if (s[0]=='-')
        {
            u=read();v=read();cut(u,v);
            u=read();v=read();link(u,v);
        }
        else {u=read();v=read();printf("%d\n",ask(u,v));}
    }
    return 0;
}