看了一下题,二话没说,想拍一个树链剖分,像线段树维护一下4个值就行了,可是想想树链剖分那长长的代码,额~(⊙o⊙)…
突然想到一句话,一切尽动态树。
先把建立一颗树吧 ,这里用1作为根, 这样的话这棵树就已经定型了。 刚开始每个节点只记录双亲。 这样任意两个节点 向着根所走过的路 要吗在路中间有交点,要么在根上有交点,要么就直接交与这两个点的某一个点了。利用这个性质我们可以yy很多东西呀~~~
#define fi freopen("in.txt","r",stdin)
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
#define sfint(x) scanf("%d",&x)
#define sfint2(x,y) scanf("%d%d",&x,&y)
#define sfint3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define sfstr(c) scanf("%s",c)
#define pfint(x) printf("%d\n",x)
#define fr(i,s,n) for(i=s;i<n;++i)
#define _fr(i,n,s) for(i=n-1;i>=s;--i)
#define cl(a) memset(a,0,sizeof(a))
const int NMax =100100;
const int M = 200010;
struct Edg
{
int u,v,nxt;
}edg[M];
int tote,head[NMax];
int num;
void init(){
tote = 0;
memset(head,-1,sizeof(head));
}
inline void addedg(int u,int v){
edg[tote].u=u;edg[tote].v=v;edg[tote].nxt=head[u];head[u]=tote++;
};
struct node
{
int val,mx,lmx,rmx,sum,siz;
bool chg;
node *l,*r,*f;
void Chg(int x){
chg = 1;
val = x;
sum = x*siz;
mx = lmx = rmx = (x > 0) ? sum : 0;
}
void down();
void update() {
siz = l->siz + r->siz +1;
sum = l->sum + r->sum + val;
mx = max(max(l->mx,r->mx),l->rmx+r->lmx+val);
lmx = max(l->lmx,l->sum+val+r->lmx);
rmx = max(r->rmx,r->sum+val+l->rmx);
}
} nodes[NMax],*nil=nodes;
int n,m;
void node::down(){
if (chg){
if (l!=nil) l->Chg(val);
if (r!=nil) r->Chg(val);
chg = 0;
}
}
class Lct
{
public:
void zig(node *p)
{
node *q=p->f,*y=q->f;
q->down();p->down();
if ((q->l=p->r))q->l->f=q;
p->r=q;
q->f=p;
p->f=y;
if (y!=nil)
{
if (y->l==q)y->l=p;
else if (y->r==q)y->r=p;
}
q->update();
}
void zag(node *p)
{
node *q=p->f,*y=q->f;
q->down(); p->down();
if ((q->r=p->l))q->r->f=q;
p->l=q;
q->f=p;
p->f=y;
if (y!=nil)
{
if (y->l==q)y->l=p;
else if (y->r==q)y->r=p;
}
q->update();
}
void Splay(node *p)
{
p->down();
while ((p->f)!=nil && (p->f->l==p || p->f->r==p))
{
node *q=p->f,*y=q->f;
if (y!=nil && y->l==q)
{
if (q->l==p)zig(q),zig(p);
else zag(p),zig(p);
}
else if (y!=nil && y->r==q)
{
if (q->r==p)zag(q),zag(p);
else zig(p),zag(p);
}
else
{
if (q->l==p)zig(p);
else zag(p);
}
}
p->update();
}
node *Expose(node *p){
node *q;
for (q=nil; p!=nil; p=p->f){
Splay(p);
p->r=q;
(q=p)->update();
}
return q;
}
void change(int x,int y,int c){
node *p=nodes+x,*q=nodes+y;
Expose(p);
node * root;
for(root = nil; q!=nil; q=q->f){
Splay(q);
if (q->f==nil) {
q->r->Chg(c);root->Chg(c);q->val = c;
}
q->r = root;
root = q;
root->update();
}
}
int Ask(int x,int y) {
node *p=nodes+x,*q=nodes+y;
Expose(p);
node * root;
for(root = nil; q!=nil; q=q->f){
Splay(q);
if (q->f==nil) {
int ans = max(q->r->mx,root->mx);
ans = max(ans,q->r->lmx+root->lmx+q->val);
return ans;
}e
q->r = root;
root = q;
root->update();
}
}
}lct;
int q[NMax];
void bfs(){
int f=0,r=1,i,u,v;
q[0] = 1;
for (i=0;i<=n;i++)nodes[i].f=nil;
while(f!=r){
u = q[f++];
for(i = head[u];i!=-1;i=edg[i].nxt){
v = edg[i].v;
if (v!=1 && nodes[v].f == nil){
nodes[v].f=nodes+u;
q[r++] = v;
}
}
}
}
void make_map(){
int i,u,v;
sfint(n);
fr(i , 1,n+1){
sfint(num);
nodes[i].siz =1;
nodes[i].val = nodes[i].sum = nodes[i].mx = nodes[i].lmx = nodes[i].rmx = num;
nodes[i].l = nodes[i].r = nil;
}
init();
fr(i,0,n-1){
sfint2(u,v);
addedg(u,v);
addedg(v,u);
}
bfs();
}
void solve(){
int i,op,u,v,w;
sfint(m);
fr(i,0,m){
sfint(op);
if (op ==1){
sfint2(u,v);
pfint(lct.Ask(u,v));
}
else{
sfint3(u,v,w);
lct.change(u,v,w);
}
}
}
int main()
{
#ifdef loca
fi;
#endif
nil->siz = 0;nil->l = nil->r = nil;nil->mx = nil->lmx=nil->rmx = nil->val = 0;
make_map();
solve();
return 0;
}