codevs 3305 水果姐逛水果街Ⅱ&&codevs3006

题目描述 Description

水果姐第二天心情也很不错,又来逛水果街。

突然,cgh又出现了。cgh施展了魔法,水果街变成了树结构(店与店之间只有一条唯一的路径)。

同样还是n家水果店,编号为1~n,每家店能买水果也能卖水果,并且同一家店卖与买的价格一样。

cgh给出m个问题,每个问题要求水果姐从第x家店出发到第y家店,途中只能选一家店买一个水果,然后选一家店(可以是同一家店,但不能往回走)卖出去。求最多可以赚多少钱。

水果姐向学过oi的你求助。

输入描述 Input Description

第一行n,表示有n家店

下来n个正整数,表示每家店一个苹果的价格。

下来n-1行,每行两个整数x,y,表示第x家店和第y家店有一条边。

下来一个整数m,表示下来有m个询问。

下来有m行,每行两个整数x和y,表示从第x家店出发到第y家店。

输出描述 Output Description

有m行。

每行对应一个询问,一个整数,表示面对cgh的每次询问,水果姐最多可以赚到多少钱。

样例输入 Sample Input

10
16 5 1 15 15 1 8 9 9 15 
1 2
1 3
2 4
2 5
2 6
6 7
4 8
1 9
1 10
6
9 1
5 1
1 7
3 3
1 1
3 6

样例输出 Sample Output

7
11
7
0
0
15

数据范围及提示 Data Size & Hint

0<=苹果的价格<=10^8

0<n<=200000

0<m<=10000

—————————————————————

算是一道lct的裸题了吧

只有查询无修改 注意一下up就可以了

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL unsigned int
using namespace std;
const int M=250007; 
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int c[M][2],fa[M],rev[M];
struct node{int v,mx,mn,lr,rl;}tr[M];
int n,m;
bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void up(int x){
    int l=c[x][0],r=c[x][1];
    tr[x].mx=tr[x].mn=tr[x].v;
    tr[x].lr=tr[x].rl=0;
    if(l){
        tr[x].lr=max(tr[l].lr,tr[x].mx-tr[l].mn);
        tr[x].rl=max(tr[l].rl,tr[l].mx-tr[x].mn);
        tr[x].mx=max(tr[x].mx,tr[l].mx);
        tr[x].mn=min(tr[x].mn,tr[l].mn);
    }
    if(r){
        tr[x].lr=max(tr[x].lr,tr[r].lr);
        tr[x].lr=max(tr[x].lr,tr[r].mx-tr[x].mn);
        tr[x].rl=max(tr[x].rl,tr[r].rl);
        tr[x].rl=max(tr[x].rl,tr[x].mx-tr[r].mn);
        tr[x].mx=max(tr[x].mx,tr[r].mx);
        tr[x].mn=min(tr[x].mn,tr[r].mn);
    }
}
void modify(int x){
    rev[x]^=1;
    swap(c[x][0],c[x][1]);
    swap(tr[x].lr,tr[x].rl);
}
void down(int x){    
    if(rev[x]){
        int l=c[x][0],r=c[x][1];
        modify(l); modify(r);
        rev[x]=0;
    }
}
void rotate(int x){
    int y=fa[x],z=fa[y],l=0,r=1;
    if(c[y][1]==x) l=1,r=0;
    if(!isrt(y)) c[z][c[z][1]==y]=x;
    fa[y]=x; fa[x]=z; fa[c[x][r]]=y;
    c[y][l]=c[x][r]; c[x][r]=y;
    up(y);
}
int st[M],top,S;
void splay(int x){
    st[++top]=x; for(int i=x;!isrt(i);i=fa[i]) st[++top]=fa[i];
    while(top) down(st[top--]);
    while(!isrt(x)){
        int y=fa[x],z=fa[y];
        if(!isrt(y)){
            if(c[z][0]==y^c[y][0]==x) rotate(x);
            else rotate(y);
        }
        rotate(x);
    }up(x);
}
void acs(int x0){
    for(int x=x0,y=0;x;splay(x),c[x][1]=y,up(x),y=x,x=fa[x]);
    splay(x0);
}
void mrt(int x){acs(x); modify(x);}
void link(int x,int y){mrt(x); fa[x]=y;}
void split(int x,int y){mrt(x); acs(y);}
int main()
{
    int x,y;
    n=read(); 
    for(int i=1;i<=n;i++) tr[i].v=read();
    for(int i=1;i<n;i++) x=read(),y=read(),link(x,y);
    m=read();
    for(int i=1;i<=m;i++){
        x=read(); y=read();
        split(x,y);
        printf("%d\n",tr[y].lr);
    }
    return 0;
}
View Code

3006比3005就多了一个修改 代码也就多一行QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL unsigned int
using namespace std;
const int M=250007; 
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int c[M][2],fa[M],rev[M];
struct node{int v,mx,mn,lr,rl;}tr[M];
int n,m;
bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void up(int x){
    int l=c[x][0],r=c[x][1];
    tr[x].mx=tr[x].mn=tr[x].v;
    tr[x].lr=tr[x].rl=0;
    if(l){
        tr[x].lr=max(tr[l].lr,tr[x].mx-tr[l].mn);
        tr[x].rl=max(tr[l].rl,tr[l].mx-tr[x].mn);
        tr[x].mx=max(tr[x].mx,tr[l].mx);
        tr[x].mn=min(tr[x].mn,tr[l].mn);
    }
    if(r){
        tr[x].lr=max(tr[x].lr,tr[r].lr);
        tr[x].lr=max(tr[x].lr,tr[r].mx-tr[x].mn);
        tr[x].rl=max(tr[x].rl,tr[r].rl);
        tr[x].rl=max(tr[x].rl,tr[x].mx-tr[r].mn);
        tr[x].mx=max(tr[x].mx,tr[r].mx);
        tr[x].mn=min(tr[x].mn,tr[r].mn);
    }
}
void modify(int x){
    rev[x]^=1;
    swap(c[x][0],c[x][1]);
    swap(tr[x].lr,tr[x].rl);
}
void down(int x){    
    if(rev[x]){
        int l=c[x][0],r=c[x][1];
        modify(l); modify(r);
        rev[x]=0;
    }
}
void rotate(int x){
    int y=fa[x],z=fa[y],l=0,r=1;
    if(c[y][1]==x) l=1,r=0;
    if(!isrt(y)) c[z][c[z][1]==y]=x;
    fa[y]=x; fa[x]=z; fa[c[x][r]]=y;
    c[y][l]=c[x][r]; c[x][r]=y;
    up(y);
}
int st[M],top,S;
void splay(int x){
    st[++top]=x; for(int i=x;!isrt(i);i=fa[i]) st[++top]=fa[i];
    while(top) down(st[top--]);
    while(!isrt(x)){
        int y=fa[x],z=fa[y];
        if(!isrt(y)){
            if(c[z][0]==y^c[y][0]==x) rotate(x);
            else rotate(y);
        }
        rotate(x);
    }up(x);
}
void acs(int x0){
    for(int x=x0,y=0;x;splay(x),c[x][1]=y,up(x),y=x,x=fa[x]);
    splay(x0);
}
void mrt(int x){acs(x); modify(x);}
void link(int x,int y){mrt(x); fa[x]=y;}
void split(int x,int y){mrt(x); acs(y);}
int main()
{
    int k,x,y;
    n=read(); 
    for(int i=1;i<=n;i++) tr[i].v=read();
    for(int i=1;i<n;i++) x=read(),y=read(),link(x,y);
    m=read();
    for(int i=1;i<=m;i++){
        k=read();
        x=read(); y=read();
        if(k) split(x,y),printf("%d\n",tr[y].lr);
        else splay(x),tr[x].v=y,up(x);
    }
    return 0;
}
View Code

 

posted @ 2017-08-30 19:12  友人Aqwq  阅读(189)  评论(0编辑  收藏  举报