zoukankan      html  css  js  c++  java
  • BZOJ2631 tree(伍一鸣) LCT 秘制标记

    这个题一看就是裸地LCT嘛,但是我wa了好几遍,这秘制标记......

    注意事项:I.*对+有贡献 II.先下传*再下传+(因为我们已经维护了+,不能再让*对+产生贡献)III.维护+用到size

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define MAXN 100005
    #define P 51061
    using namespace std;
    inline unsigned int read()
    {
        unsigned int sum=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9')
        {
           sum=(sum<<1)+(sum<<3)+ch-'0';
           ch=getchar();
        }
        return sum;
    }
    struct LCT
    {
        struct Node
        {
            Node *ch[2],*f;
            unsigned int key,multi,pluss,sum,size;
            bool rev;
            void pushup()
            {
                sum=(key+ch[0]->sum+ch[1]->sum)%P;
                size=ch[0]->size+1+ch[1]->size;
            }
        }null[MAXN];
        void swap(Node *&x,Node *&y)
        {
            Node *temp=x;
            x=y;
            y=temp;
        }
        void pushdown(Node *p)
        {
            if(p->rev)
            {
                p->ch[0]->rev^=1;
                p->ch[1]->rev^=1;
                swap(p->ch[0],p->ch[1]);
                p->rev=0;
            }
            if(p->multi!=1)
            {
                p->ch[0]->sum=(p->ch[0]->sum*p->multi)%P;
                p->ch[0]->key=(p->ch[0]->key*p->multi)%P;
                p->ch[0]->pluss=(p->ch[0]->pluss*p->multi)%P;
                p->ch[0]->multi=(p->ch[0]->multi*p->multi)%P;
                p->ch[1]->sum=(p->ch[1]->sum*p->multi)%P;
                p->ch[1]->key=(p->ch[1]->key*p->multi)%P;
                p->ch[1]->pluss=(p->ch[1]->pluss*p->multi)%P;
                p->ch[1]->multi=(p->ch[1]->multi*p->multi)%P;
                p->multi=1;
            }
            if(p->pluss)
            {
                if(p->ch[1]!=null)
                {
                   p->ch[1]->sum=(p->ch[1]->sum+p->pluss*p->ch[1]->size)%P;
                   p->ch[1]->key=(p->ch[1]->key+p->pluss)%P;
                   p->ch[1]->pluss=(p->ch[1]->pluss+p->pluss)%P;
                }
                if(p->ch[0]!=null)
                {
                   p->ch[0]->sum=(p->ch[0]->sum+p->pluss*p->ch[0]->size)%P;
                   p->ch[0]->key=(p->ch[0]->key+p->pluss)%P;
                   p->ch[0]->pluss=(p->ch[0]->pluss+p->pluss)%P;
                }
                p->pluss=0;
            }
        }
        void Init()
        {
           null->ch[1]=null->ch[0]=null->f=null;
           for(unsigned int i=1;i<MAXN;i++)
            null[i].ch[0]=null[i].ch[1]=null[i].f=null,null[i].sum=null[i].key=null[i].multi=1,null[i].pluss=0;
        }
        bool isroot(Node *p)
        {
           return p->f->ch[0]!=p&&p->f->ch[1]!=p;
        }
        unsigned int get(Node *p)
        {
           return p->f->ch[1]==p;
        }
        void rotate(Node *p)
        {
           Node *fa=p->f,*pa=fa->f;
           unsigned int j=get(p);
           if(!isroot(fa))pa->ch[get(fa)]=p;
           if((fa->ch[j]=p->ch[j^1])!=null)fa->ch[j]->f=fa;
           fa->f=p;
           p->f=pa;
           p->ch[j^1]=fa;
           fa->pushup();
           p->pushup();
        }
        void spaly(Node *p)
        {
            pushdown(p);
            for(Node *fa=p->f;!isroot(p);rotate(p),fa=p->f)
            if(!isroot(fa))
            {
                pushdown(fa->f),pushdown(fa),pushdown(p);
                rotate(get(fa)==get(p)?fa:p);
            }
            else 
                pushdown(fa),pushdown(p);
        }
        void expose(Node *x)
        {
            Node *y=null;
            while(x!=null)
            {
               spaly(x);
               x->ch[1]=y;
               x->pushup();
               y=x;
               x=x->f;
            }
        }
        void make_root(Node *p)
        {
            expose(p);
            spaly(p);
            p->rev^=1;
        }
        void cut(unsigned int a,unsigned int b)
        {
            Node *x=null+a,*y=null+b;
            make_root(x);
            expose(y);
            spaly(y);
            y->ch[0]->f=null;
            y->ch[0]=null;
            y->pushup();
        }
        void link(unsigned int a,unsigned int b)
        {
            Node *x=null+a,*y=null+b;
            make_root(x);
            x->f=y;
        }
        void up(unsigned int a,unsigned int b,unsigned int c)
        {
            Node *x=null+a,*y=null+b;
            make_root(x);
            expose(y);
            spaly(y);
            y->pluss=(y->pluss+c)%P;
            y->key=(y->key+c)%P;
            y->sum=(y->sum+y->size*c)%P;
        }
        void UUP(unsigned int a,unsigned int b,unsigned int c)
        {
            Node *x=null+a,*y=null+b;
            make_root(x);
            expose(y);
            spaly(y);
            y->multi=(y->multi*c)%P;
            y->key=(y->key*c)%P;
            y->sum=(y->sum*c)%P;
            y->pluss=(y->pluss*c)%P;
        }
        unsigned int query(unsigned int a,unsigned int b)
        {
            Node *x=null+a,*y=null+b;
            make_root(x);
            expose(y);
            spaly(y);
            return y->sum;
        }
    }YY;
    int main()
    {
        YY.Init();
        unsigned int n=read(),m=read();
        for(unsigned int i=1;i<n;i++)
        {
           unsigned int x=read(),y=read();
           YY.link(x,y);
        }
        for(unsigned int i=1,x,y,z,a,b;i<=m;i++)
        {
           char ch;
           cin>>ch;
           x=read(),y=read();
           switch(ch)
           {
               case '*':z=read();
                        YY.UUP(x,y,z);
                        break;
               case '+':z=read();
                        YY.up(x,y,z);
                        break;
               case '-':a=read(),b=read();
                        YY.cut(x,y);
                        YY.link(a,b);
                        break;
               case '/':printf("%d
    ",YY.query(x,y));
                        break;
           }
        }
        return 0;
    }
  • 相关阅读:
    NYOJ题目28大数阶乘
    网页小图标设置
    Sass中文乱码问题(手动编译和watch编译)
    设计模式之构建者模式(Builder):初步理解
    Struts2之类型转换器
    css设置网页文本选中样式
    由超市临时储物柜引发的一点设计随想...
    前端资源相关参考资料
    Struts2拦截器之ExceptionMappingInterceptor(异常映射拦截器)
    Struts2之OGNL
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7157157.html
Copyright © 2011-2022 走看看