zoukankan      html  css  js  c++  java
  • Codevs 3305 水果姐逛水果街Ⅱ 倍增LCA

     时间限制: 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

     
    题解:
    和3304同理,改为树上倍增即可。
    处理信息特别麻烦。。。
     
    代码略丑。。。
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define MAXN 200010
      4 #define INF 1e9
      5 struct node
      6 {
      7     int begin,end,next;
      8 }edge[MAXN*2];
      9 int cnt,Head[MAXN],n,P[MAXN][18],mx[MAXN][18],mn[MAXN][18],lc[MAXN][18],rc[MAXN][18],deep[MAXN],a[MAXN];
     10 bool vis[MAXN];
     11 void addedge(int bb,int ee)
     12 {
     13     edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt;
     14 }
     15 void addedge1(int bb,int ee)
     16 {
     17     addedge(bb,ee);addedge(ee,bb);
     18 }
     19 int read()
     20 {
     21     int s=0,fh=1;char ch=getchar();
     22     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
     23     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
     24     return s*fh;
     25 }
     26 void dfs1(int u)
     27 {
     28     int i,j,v;
     29     vis[u]=true;
     30     for(j=1;(1<<j)<=n;j++)
     31     {
     32         P[u][j]=P[P[u][j-1]][j-1];
     33         mx[u][j]=max(mx[u][j-1],mx[P[u][j-1]][j-1]);
     34         mn[u][j]=min(mn[u][j-1],mn[P[u][j-1]][j-1]);
     35         lc[u][j]=max(lc[u][j-1],lc[P[u][j-1]][j-1]);
     36         lc[u][j]=max(lc[u][j],mx[P[u][j-1]][j-1]-mn[u][j-1]);
     37         rc[u][j]=max(rc[u][j-1],rc[P[u][j-1]][j-1]);
     38         rc[u][j]=max(rc[u][j],mx[u][j-1]-mn[P[u][j-1]][j-1]);
     39     }
     40     for(i=Head[u];i!=-1;i=edge[i].next)
     41     {
     42         v=edge[i].end;
     43         if(vis[v]==false)
     44         {
     45             deep[v]=deep[u]+1;
     46             P[v][0]=u;
     47             mx[v][0]=max(a[u],a[v]);//最大值
     48             mn[v][0]=min(a[u],a[v]);//最小值
     49             lc[v][0]=max(0,a[u]-a[v]);//从i点到达fa[i][j]点的最大利润.
     50             rc[v][0]=max(0,a[v]-a[u]);//从fa[i][j]点到达i点的最大利润.
     51             dfs1(v);
     52         }
     53     }
     54 }
     55 /*void Ycl()
     56 {
     57     int i,j;
     58     for(j=1;(1<<j)<=n;j++)
     59     {
     60         for(i=1;i<=n;i++)
     61         {
     62             if(P[i][j-1]!=-1)
     63             {
     64                 P[i][j]=P[P[i][j-1]][j-1];
     65                 mx[i][j]=max(mx[i][j],max(mx[i][j-1],mx[P[i][j-1]][j-1]));
     66                 mn[i][j]=min(mn[i][j],min(mn[i][j-1],mn[P[i][j-1]][j-1]));
     67                 lc[i][j]=max(lc[i][j],max(lc[i][j-1],lc[P[i][j-1]][j-1]));
     68                 lc[i][j]=max(lc[i][j],mx[P[i][j-1]][j-1]-mn[i][j-1]);
     69                 rc[i][j]=max(rc[i][j],max(rc[i][j-1],rc[P[i][j-1]][j-1]));
     70                 rc[i][j]=max(rc[i][j],mx[i][j-1]-mn[P[i][j-1]][j-1]);
     71             }
     72         }
     73     }
     74 }*/
     75 int LCA(int x,int y)
     76 {
     77     int i,j;
     78     if(deep[x]<deep[y])swap(x,y);
     79     for(i=0;(1<<i)<=deep[x];i++);i--;
     80     for(j=i;j>=0;j--)if(deep[x]-(1<<j)>=deep[y])x=P[x][j];
     81     if(x==y)return x;
     82     for(j=i;j>=0;j--)
     83     {
     84         if(P[x][j]!=-1&&P[x][j]!=P[y][j])
     85         {
     86             x=P[x][j];
     87             y=P[y][j];
     88         }
     89     }
     90     return P[x][0];
     91 }
     92 int MAX1(int x,int y)
     93 {
     94     int i,j,maxv=-INF;
     95     if(deep[x]<deep[y])swap(x,y);
     96     for(i=0;(1<<i)<=deep[x];i++);i--;
     97     for(j=i;j>=0;j--)
     98     {
     99         if(deep[x]-(1<<j)>=deep[y])
    100         {
    101             maxv=max(maxv,lc[x][j]);
    102             x=P[x][j];
    103         }
    104     }
    105     return maxv;
    106 }
    107 int MAX2(int x,int y)
    108 {
    109     int i,j,maxv=-INF;
    110     if(deep[x]<deep[y])swap(x,y);
    111     for(i=0;(1<<i)<=deep[x];i++);i--;
    112     for(j=i;j>=0;j--)
    113     {
    114         if(deep[x]-(1<<j)>=deep[y])
    115         {
    116             maxv=max(maxv,rc[x][j]);
    117             x=P[x][j];
    118         }
    119     }
    120     return maxv;
    121 }
    122 int MX(int x,int y)
    123 {
    124     int i,j,maxv=-INF;
    125     if(deep[x]<deep[y])swap(x,y);
    126     for(i=0;(1<<i)<=deep[x];i++);i--;
    127     for(j=i;j>=0;j--)
    128     {
    129         if(deep[x]-(1<<j)>=deep[y])
    130         {
    131             maxv=max(maxv,mx[x][j]);
    132             x=P[x][j];
    133         }
    134     }
    135     return maxv;
    136 }
    137 int MN(int x,int y)
    138 {
    139     int i,j,minv=INF;
    140     if(deep[x]<deep[y])swap(x,y);
    141     for(i=0;(1<<i)<=deep[x];i++);i--;
    142     for(j=i;j>=0;j--)
    143     {
    144         if(deep[x]-(1<<j)>=deep[y])
    145         {
    146             minv=min(minv,mn[x][j]);
    147             x=P[x][j];
    148         }
    149     }
    150     return minv;
    151 }
    152 int Ask(int x,int y)
    153 {
    154     int lca=LCA(x,y),xx=x,yy=y,i,j;
    155     int maxxx=-INF,minnn=INF,ans=0;
    156     if(deep[x]<deep[lca])swap(x,lca);
    157     for(i=0;(1<<i)<=deep[x];i++);i--;
    158     for(j=i;j>=0;j--)
    159     {
    160         if(deep[x]-(1<<j)>=deep[lca])
    161         {
    162             ans=max(ans,max(lc[x][j],mx[x][j]-minnn));
    163             minnn=min(mn[x][j],minnn);
    164             x=P[x][j];
    165         }
    166     }
    167     if(deep[y]<deep[lca])swap(y,lca);
    168     for(i=0;(1<<i)<=deep[y];i++);i--;
    169     for(j=i;j>=0;j--)
    170     {
    171         if(deep[y]-(1<<j)>=deep[lca])
    172         {
    173             ans=max(ans,max(rc[y][j],maxxx-mn[y][j]));
    174             maxxx=max(mx[y][j],maxxx);
    175             y=P[y][j];
    176         }
    177     }
    178     return max(ans,maxxx-minnn);
    179 }
    180 int main()
    181 {
    182     int bb,ee,i,j,m,x,y,ans,lca;
    183     n=read();
    184     for(i=1;i<=n;i++)a[i]=read();
    185     memset(Head,-1,sizeof(Head));cnt=1;
    186     for(i=1;i<n;i++)
    187     {
    188         bb=read();ee=read();
    189         addedge1(bb,ee);
    190     }
    191     memset(P,-1,sizeof(P));
    192     /*for(j=1;(1<<j)<=n;j++)
    193     {
    194         for(i=1;i<=n;i++)
    195         {
    196             mn[i][j]=0;mx[i][j]=0;
    197             lc[i][j]=rc[i][j]=0;
    198         }
    199     }*/
    200     dfs1(1);//Ycl();
    201     m=read();
    202     for(i=1;i<=m;i++)
    203     {
    204         x=read();y=read();
    205         if(x==y)printf("0
    ");
    206         else// if(x<y)
    207         {
    208             printf("%d
    ",Ask(x,y));
    209             //if(x>y)swap(x,y);
    210             /*lca=LCA(x,y);
    211             ans=0;
    212             ans=max(ans,MAX1(x,lca));
    213             ans=max(ans,MAX2(lca,y));
    214             ans=max(ans,MX(lca,y)-MN(x,lca));
    215             printf("%d
    ",ans);*/
    216         }
    217         /*else
    218         {
    219             lca=LCA(x,y);
    220             ans=-INF;
    221             ans=max(ans,MAX1(x,lca));
    222             ans=max(ans,MAX2(y,lca));
    223             ans=max(ans,MX(y,lca)-MN(x,lca));
    224             printf("%d
    ",ans);
    225         }*/
    226     }
    227     return 0;
    228 }
    View Code
  • 相关阅读:
    JQuery实现滚动广告
    写链表时报HEAP CORRUPTION DETECTED: before Normal block
    ubuntu 运行sh提示unexpected operator
    解决Visual C++ 6 绿色版 Gallery 目录为空的问题
    写堆栈的时候报的奇怪的错。
    ubuntu开启SSH服务
    ubuntu修改runlevel
    Hello.Android.3rd.Edition——读书笔记
    java程序员应该掌握的10技能
    格式化数字的方法
  • 原文地址:https://www.cnblogs.com/Var123/p/5275743.html
Copyright © 2011-2022 走看看