您的位置:首页 > 产品设计 > UI/UE

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

2013-03-27 00:37 447 查看
题目链接: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
,*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
;
int head
,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;
}





                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: