SPOJ 6779 Can you answer these queries VII(动态树)

题目链接:http://www.spoj.com/problems/GSS7/

题意:一棵树,每个节点有一个权值。两种操作:(1)将某条路经的权值统一修改为某个值;(2)询问某个路径上最大的连续和。

思路:节点保存sum,size,val,Max,LMax,RMax。

 
   
const int N=200005;



struct node

{

    int isRoot,val,sum,Max,LMax,RMax,Size;

    int isChanged;

    node *c[2],*f;



    void change(int x)

    {

        isChanged=1;

        val=x;

        sum=Size*x;

        Max=LMax=RMax=x>0?sum:0;

    }

};



node a[N],*nullNode;

int n;



void up(node *p)

{

    p->Size=p->c[0]->Size+p->c[1]->Size+1;

    p->sum=p->c[0]->sum+p->c[1]->sum+p->val;



    p->Max=max(max(p->c[0]->Max,p->c[1]->Max),p->c[0]->RMax+p->val+p->c[1]->LMax);

    p->LMax=max(p->c[0]->LMax,p->c[0]->sum+p->val+p->c[1]->LMax);

    p->RMax=max(p->c[1]->RMax,p->c[1]->sum+p->val+p->c[0]->RMax);

}



void pushDown(node *p)

{

    if(p->isChanged)

    {

        if(p->c[0]!=nullNode) p->c[0]->change(p->val);

        if(p->c[1]!=nullNode) p->c[1]->change(p->val);

        p->isChanged=0;

    }

}



void rotate(node *p,int k)

{

    node *q=p->f;

    pushDown(q);

    pushDown(p);

    q->c[k]=p->c[!k];

    if(p->c[!k]!=nullNode) p->c[!k]->f=q;

    p->c[!k]=q;

    p->f=q->f;

    if(q->f!=nullNode)

    {

        if(p->f->c[0]==q) p->f->c[0]=p;

        if(p->f->c[1]==q) p->f->c[1]=p;

    }

    q->f=p;

    up(q);

    p->isRoot=q->isRoot;

    q->isRoot=0;

}



int isRoot(node *p)

{

    return p->f==nullNode||p->f->c[0]!=p&&p->f->c[1]!=p;

}





void splay(node *p)

 {

     pushDown(p);

     while (!isRoot(p))

     {

         if(isRoot(p->f))

         {

             if(p==p->f->c[0]) rotate(p,0);

             else rotate(p,1);

         }

         else

         {

             if(p->f->f->c[0]==p->f)

             {

                 if(p->f->c[0]==p) rotate(p->f,0);

                 else rotate(p,1);

                 rotate(p,0);

             }

             else

             {

                 if(p->f->c[1]==p) rotate(p->f,1);

                 else rotate(p,0);

                 rotate(p,1);

             }

         }

     }

     up(p);

}



node* access(node *p)

{

    node *q=nullNode;

    while(p!=nullNode)

    {

        splay(p);

        p->c[1]->isRoot=1;

        p->c[1]=q;

        q->isRoot=0;

        up(p);

        q=p;

        p=p->f;

    }

    return q;

}





void change(int x,int y,int val)

{

    access(a+x);

    node *lca=access(a+y);

    lca->val=val;

    lca->c[1]->change(val);

    splay(a+x);

    if(a+x!=lca) a[x].change(val);

    up(lca);

}



int query(int x,int y)

{

    access(a+x);

    node *lca=access(a+y);

    splay(a+x);

    int ans;

    if(a+x!=lca)

    {

        ans=max(lca->c[1]->Max,a[x].Max);

        ans=max(ans,lca->c[1]->LMax+lca->val+a[x].LMax);

    }

    else

    {

        ans=lca->c[1]->Max;

        ans=max(ans,lca->c[1]->LMax+lca->val);

    }

    return ans;

}



struct Node

{

    int v,next;

};



Node edges[N];

int head[N],e;





void Add(int u,int v)

{

    edges[e].v=v;

    edges[e].next=head[u];

    head[u]=e++;



    edges[e].v=u;

    edges[e].next=head[v];

    head[v]=e++;

}



void build()

{

    queue<int> Q;

    Q.push(1);

    int i,u,v;

    while(!Q.empty())

    {

        u=Q.front();

        Q.pop();



        for(i=head[u];i!=-1;i=edges[i].next)

        {

            v=edges[i].v;

            if(a+v==a[u].f) continue;

            a[v].f=a+u;

            Q.push(v);

        }

    }



}





void init()

{

    nullNode=new node();

    nullNode->Size=0;

    nullNode->isChanged=0;

    nullNode->c[0]=nullNode->c[1]=nullNode->f=nullNode;

    nullNode->Max=nullNode->LMax=nullNode->RMax=nullNode->val=0;

    RD(n);

    int i,u,v,dis;

    FOR1(i,n)

    {

        RD(dis);

        a[i].c[0]=a[i].c[1]=a[i].f=nullNode;

        a[i].isRoot=1;

        a[i].Size=1;

        a[i].isChanged=0;

        a[i].sum=a[i].Max=a[i].LMax=a[i].RMax=a[i].val=dis;

    }

    clr(head,-1);

    e=0;

    FOR1(i,n-1) RD(u,v),Add(u,v);

    build();

}



int main()

{

    init();

    int a,b,c,op,m;

    RD(m);

    while(m--)

    {

        RD(op);

        if(op==1) RD(a,b),PR(query(a,b));

        else RD(a,b,c),change(a,b,c);

    }

    return 0;

}

 
   

 

 
  

你可能感兴趣的:(poj)