• BZOJ[3159]决战 LCT


    只有前四个操作的话就是LCT裸题了
    链翻转不也是LCT的基本操作吗....
    等等,翻转的是权值?
    正常的翻转改的是各个点的深度,位置与权值的对应关系并没有改变
    那么我们可以考虑维护两棵LCT,一棵维护形态,一棵维护位置
    翻转其中一个就相当于改变了对应关系
    说的不是很明白的啊....还是看看学姐的blog

    代码如下:

    #include<ctype.h>
    #include<cstdio>
    #define int long long
    #define INF 2147483647000000l
    #define N 50020
    using namespace std;
    typedef long long LL;
    inline int read(){
        int x=0,f=1;char c;
        do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c));
        do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c));
        return x*f;
    }
    inline int Max(int a,int b){return a>b?a:b;}
    inline int Min(int a,int b){return a<b?a:b;}
    inline int max3(int a,int b,int c){return Max(a,Max(b,c));}
    inline int min3(int a,int b,int c){return Min(a,Min(b,c));}
    int n,m,root,x,y,k,top;
    int fir[N];
    char c[13];
    struct Edge{
        int to,nex;
        Edge(){}
        Edge(int _,int __):to(_),nex(__){}
    }nex[N<<1];
    inline void add(int x,int y){
        nex[++top]=Edge(y,fir[x]);
        fir[x]=top;
    }
    struct Node{
        Node *ch[2],*fa,*nex;
        int sum,minn,maxx,addv,x,siz;
        bool rev;
        Node();
        inline void Pushdown();
        inline void Add(int);
        inline void Reverse();
        inline void maintain(){
            minn=min3(ch[0]->minn,ch[1]->minn,x);
            maxx=max3(ch[0]->maxx,ch[1]->maxx,x);
            sum=ch[0]->sum+ch[1]->sum+x;
            siz=ch[0]->siz+ch[1]->siz+1;
            return;
        }
        inline int dir(){
            if(fa->ch[0]==this) return 0;
            if(fa->ch[1]==this) return 1;
            return -1;
        }
    }*null,*p[N];
    inline void Swap(Node *&a,Node *&b){static Node *c;c=a;a=b;b=c;}
    Node::Node(){
        x=addv=minn=maxx=sum=rev=0;
        siz=1;
        ch[0]=ch[1]=nex=fa=null;
        return;
    }
    inline void Node::Pushdown(){
        if(addv){
            ch[0]->Add(addv);
            ch[1]->Add(addv);
        }
        if(rev) ch[0]->Reverse(),ch[1]->Reverse();
        if(nex!=null){
            if(ch[0]!=null) ch[0]->nex=nex;
            if(ch[1]!=null) ch[1]->nex=nex;
        }
        addv=rev=0;
    }
    inline void Node::Add(int k){
        if(this==null) return;
        addv=addv+k;sum=sum+k*siz;
        x+=k;minn+=k;maxx+=k;
        return;
    }
    inline void Node::Reverse(){
        if(this==null) return;
        Swap(ch[0],ch[1]);
        rev=!rev;
        return;
    }
    inline void init(){
        null=new Node;
        null->ch[0]=null->ch[1]=null->fa=null->nex=null;
        null->sum=null->x=null->siz=null->addv=null->rev=0;
        null->minn=INF;null->maxx=-INF;
        return;
    }
    void PushUp(Node *x){
        if(~x->dir()) PushUp(x->fa);
        x->Pushdown();
        return;
    }
    inline Node *K_th(Node *x,int k){
        if(x==null) return x;
        x->Pushdown();
        if(x->ch[0]->siz+1==k)
            return x;
        if(k<=x->ch[0]->siz) return K_th(x->ch[0],k);
        else return K_th(x->ch[1],k-x->ch[0]->siz-1);
    }
    inline void Rotate(Node *x,int d){
        static Node *k;
        static int di;
        k=x->ch[d^1];
        x->ch[d^1]=k->ch[d];
        if(x->ch[d^1]!=null) x->ch[d^1]->fa=x;
        k->ch[d]=x;
        if(~(di=x->dir())) x->fa->ch[di]=k;
        k->fa=x->fa;x->fa=k;
        x->maintain();k->maintain();
        return;
    }
    inline void Splay(Node *x){
        static int d;
        PushUp(x);
        while(~(d=x->dir())){
            if(x->fa->dir()==d)
                Rotate(x->fa->fa,d^1);
            Rotate(x->fa,d^1);
        }
        return;
    }
    inline void Splay_(Node *x,Node *&y){
        Splay(x);Splay(x->nex);
        y=K_th(x->nex,x->ch[0]->siz+1);
        Splay(y);
        return;
    }
    void dfs(int x,int fa){
        p[x]=new Node;p[x]->nex=new Node;
        p[x]->fa=p[fa];p[x]->nex->fa=p[fa]->nex;
        for(int i=fir[x];i;i=nex[i].nex){
            if(nex[i].to==fa) continue;
            dfs(nex[i].to,x);
        }
    }
    inline void Access(Node *x){
        static Node *pre,*pre_,*x_;
        pre=pre_=x_=null;
        while(x!=null){
            Splay_(x,x_);
            x->nex=x_;
            x->ch[1]->nex=x_->ch[1];
            x->ch[1]=pre;x_->ch[1]=pre_;
            pre_->fa=x_;
            x->maintain();x_->maintain();
            pre=x;pre_=x_;
            x=x->fa;
        }
        return;
    }
    inline void MakeRoot(Node *x){
        static Node *k;
        Access(x);Splay_(x,k);
        x->Reverse();k->Reverse();
        return;
    }
    inline Node *Extract(Node *x,Node *y){
        static Node *y_;
        MakeRoot(x);
        Access(y);Splay_(y,y_);
        return y_;
    }
    main(){
        init();
        n=read();m=read();root=read();
        for(register int i=1;i<n;i++){
            x=read();y=read();
            add(x,y);add(y,x);
        }
        p[0]=null;
        dfs(root,0);
        for(register int i=1;i<=m;i++){
            scanf("%s",c+1);
            x=read();y=read();
            if(c[3]=='c') k=read(),Extract(p[x],p[y])->Add(k);
            else if(c[3]=='m') printf("%lld\n",Extract(p[x],p[y])->sum);
            else if(c[3]=='j') printf("%lld\n",Extract(p[x],p[y])->maxx);
            else if(c[3]=='n') printf("%lld\n",Extract(p[x],p[y])->minn);
            else Extract(p[x],p[y])->Reverse();
        }
        return 0;
    }
    
    
  • 相关阅读:
    vue2 在methods 中无法获取this对象
    mysql-set
    laravel 模板
    laravel save() 返回 null
    如何设置电脑允许远程访问并修改电脑用户密码?
    laravel报错:Unable to detect application namespace.
    b站操作系统2程序的顺序执行与并发执行
    b站计算机网络谢希仁4物理层
    b站计算机网络谢希仁2性能
    b站J数据库13之封装通用的增删改查方法
  • 原文地址:https://www.cnblogs.com/Duan2baka/p/8674381.html
Copyright © 2020-2023  润新知