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;
    }
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    JavaScript cookie详解
    Javascript数组的排序:sort()方法和reverse()方法
    javascript中write( ) 和 writeln( )的区别
    div做表格
    JS 盒模型 scrollLeft, scrollWidth, clientWidth, offsetWidth 详解
    Job for phpfpm.service failed because the control process exited with error code. See "systemctl status phpfpm.service" and "journalctl xe" for details.
    orm查询存在价格为空问题
    利用救援模式破解系统密码
    SSH服务拒绝了密码
    C# 调用 C++ DLL 中的委托,引发“对XXX::Invoke类型的已垃圾回收委托进行了回调”错误的解决办法
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7543183.html
Copyright © 2011-2022 走看看