zoukankan      html  css  js  c++  java
  • code vs 3305 水果姐逛水果街Ⅱ

     时间限制: 2 s
     空间限制: 256000 KB
     题目等级 : 钻石 Diamond
     
     
     
    题目描述 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

    思路:lca维护区间差值。

    #include<cstdio>
    #include<iostream>
    #include<vector>
    #include<cstring>
    using namespace std;
    const int N=200001,pow=20,maxx=999999;
    vector<int> g[N];
    int d[N],f[N][pow],maxv[N][pow]={0},minv[N][pow],diff[N][pow]={0},dife[N][pow]={0},q[N];
    //  diff:顺区间最大差
    //  dife:逆区间最大差 
    void dfs(int x,int fa)
    {
        int i,t;
        maxv[x][0]=max(q[x],q[fa]);
        minv[x][0]=min(q[x],q[fa]);
        diff[x][0]=q[x]-q[fa];
        dife[x][0]=q[fa]-q[x];
        d[x]=d[fa]+1;
        f[x][0]=fa;
        for(i=1;i<pow;i++)
        {
            f[x][i]=f[f[x][i-1]][i-1];
            maxv[x][i]=max(maxv[x][i-1],maxv[f[x][i-1]][i-1]);
            minv[x][i]=min(minv[x][i-1],minv[f[x][i-1]][i-1]);
            diff[x][i]=max(maxv[x][i-1]-minv[f[x][i-1]][i-1],max(diff[x][i-1],diff[f[x][i-1]][i-1]));
            dife[x][i]=max(maxv[f[x][i-1]][i-1]-minv[x][i-1],max(dife[x][i-1],dife[f[x][i-1]][i-1]));
        }
        for(i=0;i<g[x].size();i++)
            if(g[x][i]!=fa)
                dfs(g[x][i],x);
    }
    int lca(int a,int b)
    {
        int i,t,total=0,flag=0,maxn=0,minn=maxx;
        if(d[a]>d[b]){
            flag=1;
            a^=b,b^=a,a^=b;
        }
        if(d[a]<d[b]){
            t=d[b]-d[a];
            for(i=0;i<pow;i++)
                if(t&(1<<i)){
                    if(!flag){
                        total=max(total,maxn-minv[b][i]);
                        maxn=max(maxn,maxv[b][i]);
                        total=max(total,diff[b][i]);
                    }
                    else{
                        total=max(total,maxv[b][i]-minn);
                        minn=min(minn,minv[b][i]);
                        total=max(total,dife[b][i]);
                    }
                    b=f[b][i];
                }
            if(!flag) minn=q[a];
            else maxn=q[a];
        }
        else{
            if(!flag) minn=q[a],maxn=q[b];
            else maxn=q[a],minn=q[b];
        }
        if(a!=b){
            for(i=pow-1;i>=0;i--)
                if(f[a][i]!=f[b][i]){
                    if(!flag){
                        total=max(total,maxv[a][i]-minn);
                        total=max(total,maxn-minv[b][i]);
                        total=max(total,dife[a][i]);
                        total=max(total,diff[b][i]);
                        maxn=max(maxn,maxv[b][i]);    
                        minn=min(minn,minv[a][i]);                    
                    }
                    else{
                        total=max(total,maxv[b][i]-minn);
                        total=max(total,maxn-minv[a][i]);
                        total=max(total,diff[a][i]);
                        total=max(total,dife[b][i]);
                        maxn=max(maxn,maxv[a][i]);
                        minn=min(minn,minv[b][i]);
                    }
                    a=f[a][i],b=f[b][i];
                }
            total=max(total,maxn-minn);
            if(!flag){
                total=max(total,maxn-q[f[a][0]]);
                total=max(total,q[f[b][0]]-minn);
            }
            else{
                total=max(total,maxn-q[f[b][0]]);
                total=max(total,q[f[a][0]]-minn);
            }
        }
        return total;
    }
    int main(){
        memset(minv,27,sizeof(minv));
        int n,m,i,j,x,y;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d",&q[i]);
        for(i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
        }
        for(i=0;i<g[1].size();i++)
            dfs(g[1][i],1);
        scanf("%d",&m);
        for(i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    对象关系一对多转换为一对一的方案——中介者模式总结
    接口转换的利器——适配器模式总结
    多线程场景设计利器:分离方法的调用和执行——命令模式总结
    对比总结三个工厂模式(简单工厂,工厂方法,抽象工厂)
    创建多个“产品”的方式——工厂方法模式总结
    Java反射+简单工厂模式总结
    最简单的设计模式——单例模式的演进和推荐写法(Java 版)
    对复合(协作)算法/策略的封装方法——装饰模式总结
    Java对象序列化全面总结
    创建产品族的方式——抽象工厂模式
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7543183.html
Copyright © 2011-2022 走看看