zoukankan      html  css  js  c++  java
  • codevs水果姐逛水果街3

    3306 水果姐逛水果街Ⅲ

     

    时间限制: 2 s
    空间限制: 256000 KB
    题目等级 : 大师 Master
     
     
     
    题目描述 Description

    连续两天都没有被cgh难倒,水果姐心情很不错,第三天又来逛水果街。

    今天cgh早早就来到了水果街等水果姐,因为他带来了帮手cys。cgh的魔法是把水果街变成树结构,而cys的魔法是瞬间改变某家店的水果价格。一边问一边改,绝不给水果姐思考的时间!

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

    cgh和cys一共有m个操作。

    操作的格式为

    0 x y 获 1 x y

    如果操作类型是0,表示cys把第x家店的价格改为y

    如果操作类型是1,则表示要求水果姐从第x家店出发到第y家店,途中只能选一家店买一个水果,然后选一家店(可以是同一家店,但不能往回走)卖出去。并且输出最多可以赚多少钱。

    这题是给天牛做的。

    输入描述 Input Description

    第一行n,表示有n家店

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

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

    下来一个整数m,表示下来有m个操作。

    下来有m行,每行三个整数,表示一次操作。

    输出描述 Output Description

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

    样例输入 Sample Input

    4
    16 5 1 15
    1 2
    1 3
    2 4
    3
    1 3 4
    0 3 17
    1 4 3

    样例输出 Sample Output

    15
    12

    数据范围及提示 Data Size & Hint

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

    0<n<=2*10^5

    0<m<=10^5

    题目大意就是给定起点和终点,求这条路径上的最大值减最小值,最小值要在最大值的前面。还有单点修改操作。
    先树链剖分。
    对于剖出来的几段路径,分情况讨论。
    设路径是从xy
    对于一段xLCA的路径,max-前面查询的最小值,yLCA的路径的最大值-min可以更新答案。
    yLCA的路径类似。
    还要考虑线段树中的可以更新答案的情况,维护两个东西:左区间-右区间的最大和右区间-左区间的最大就可以了。
    实现很麻烦啊。
      1 #include <algorithm>
      2 #include <iostream>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <cstdio>
      6 #include <cmath>
      7 #define maxn 500100
      8 #define ls o*2
      9 #define rs o*2+1
     10 #define mi int mid=(l+r)>>1
     11 #define inf 1999999999
     12 using namespace std;
     13 struct data{
     14   int nex,to;
     15 }e[maxn*2];
     16 int n,head[maxn],edge=0,dad[maxn],son[maxn],size[maxn],top[maxn],dfn[maxn],dfp[maxn],deep[maxn],dis[maxn];
     17 int b1[maxn*4],b2[maxn*4],b3[maxn*4],b4[maxn*4];
     18 int max(int x,int y){return x<y?y:x;}
     19 int min(int x,int y){return x<y?x:y;}
     20 void add(int from,int to){
     21   e[++edge].nex=head[from];
     22   e[edge].to=to;
     23   head[from]=edge;
     24 }
     25 void build(int o,int l,int r){
     26   if(l==r){b1[o]=b2[o]=dis[dfp[l]];return;}
     27   mi;
     28   build(ls,l,mid);
     29   build(rs,mid+1,r);
     30   b1[o]=min(b1[ls],b1[rs]);
     31   b2[o]=max(b2[ls],b2[rs]);
     32   b3[o]=max(b2[rs]-b1[ls],max(b3[ls],b3[rs]));
     33   b4[o]=max(b2[ls]-b1[rs],max(b4[ls],b4[rs]));
     34 }
     35 void dfs1(int x,int fa){
     36   size[x]++;
     37   for(int i=head[x];i;i=e[i].nex){
     38     int u=e[i].to;
     39     if(u==fa) continue;
     40     deep[u]=deep[x]+1;
     41     dad[u]=x;
     42     dfs1(u,x);
     43     size[x]+=size[u];
     44     if(size[u]>size[son[x]])son[x]=u;
     45   }
     46 }
     47 int de=0;
     48 void dfs2(int x,int fa){
     49   ++de;
     50   dfn[x]=de,dfp[de]=x;
     51   if(son[x]){
     52     top[son[x]]=top[x];
     53     dfs2(son[x],x);
     54   }
     55   for(int i=head[x];i;i=e[i].nex){
     56     int u=e[i].to;
     57     if(u==fa || u==son[x]) continue;
     58     top[u]=u;
     59     dfs2(u,x);
     60   }
     61 }
     62 void change(int o,int l,int r,int p,int w){
     63   if(l==r){b1[o]=b2[o]=w;return;}
     64   mi;
     65   if(p<=mid) change(ls,l,mid,p,w);
     66   else change(rs,mid+1,r,p,w);
     67   b1[o]=min(b1[ls],b1[rs]);
     68   b2[o]=max(b2[ls],b2[rs]);
     69   b3[o]=max(b2[rs]-b1[ls],max(b3[ls],b3[rs]));
     70   b4[o]=max(b2[ls]-b1[rs],max(b4[ls],b4[rs]));
     71 }
     72 int find_max(int o,int l,int r,int u,int v){
     73   if(l>=u && r<=v) return b2[o];
     74   if(l>v || r<u) return 0;
     75   mi;
     76   if(v<=mid) return find_max(ls,l,mid,u,v);
     77   else if(u>mid) return find_max(rs,mid+1,r,u,v);
     78   else return max(find_max(ls,l,mid,u,mid),find_max(rs,mid+1,r,mid+1,v));
     79 }
     80 int find_min(int o,int l,int r,int u,int v){
     81   if(l>=u && r<=v) return b1[o];
     82   if(l>v || r<u) return inf;
     83   mi;
     84   if(v<=mid) return find_min(ls,l,mid,u,v);
     85   else if(u>mid) return find_min(rs,mid+1,r,u,v);
     86   else return min(find_min(ls,l,mid,u,mid),find_min(rs,mid+1,r,mid+1,v));
     87 }
     88 int find_ans1(int o,int l,int r,int u,int v){
     89   if(l>=u && r<=v) return b4[o];
     90   if(l>v || r<u) return 0;
     91   int mid=(l+r)>>1;
     92   if(v<=mid) return find_ans1(ls,l,mid,u,v);
     93   else if(u>mid) return find_ans1(rs,mid+1,r,u,v);
     94   else return max(max(find_ans1(ls,l,mid,u,mid),find_ans1(rs,mid+1,r,mid+1,v)),
     95           find_max(1,1,n,u,mid)-find_min(1,1,n,mid+1,v));
     96 }
     97 int find_ans2(int o,int l,int r,int u,int v){
     98   if(l>=u && r<=v) return b3[o];
     99   if(l>v || r<u) return 0;
    100   int mid=(l+r)>>1;
    101   if(v<=mid) return find_ans2(ls,l,mid,u,v);
    102   else if(u>mid) return find_ans2(rs,mid+1,r,u,v);
    103   else return max(max(find_ans2(ls,l,mid,u,mid),find_ans2(rs,mid+1,r,mid+1,v)),
    104           find_max(1,1,n,mid+1,v)-find_min(1,1,n,u,mid));
    105 }
    106 int solve(int x,int y){
    107   int ans=0,zd1=0,zd2=0,zx1=inf,zx2=inf;
    108   while(top[x]!=top[y]){
    109     if(deep[top[x]]>deep[top[y]]){
    110       int k1=find_max(1,1,n,dfn[top[x]],dfn[x]);
    111       zd1=max(zd1,k1);
    112       ans=max(ans,find_ans1(1,1,n,dfn[top[x]],dfn[x]));
    113       ans=max(ans,k1-zx1);
    114       int k2=find_min(1,1,n,dfn[top[x]],dfn[x]);
    115       zx1=min(zx1,k2);
    116       ans=max(ans,zd2-k2);
    117       x=dad[top[x]];
    118     }
    119     else{
    120       int k1=find_min(1,1,n,dfn[top[y]],dfn[y]);
    121       zx2=min(zx2,k1);
    122       ans=max(ans,find_ans2(1,1,n,dfn[top[y]],dfn[y]));
    123       ans=max(ans,zd2-k1);
    124       int k2=find_max(1,1,n,dfn[top[y]],dfn[y]);
    125       zd2=max(zd2,k2);
    126       ans=max(ans,k2-zx1);
    127       y=dad[top[y]];
    128     }
    129   }
    130   if(deep[x]>deep[y])
    131     ans=max(ans,find_ans1(1,1,n,dfn[y],dfn[x]));
    132   else ans=max(ans,find_ans2(1,1,n,dfn[x],dfn[y]));
    133   if(deep[x]>deep[y])swap(x,y);
    134   int zx=find_min(1,1,n,dfn[x],dfn[y]);
    135   int zd=find_max(1,1,n,dfn[x],dfn[y]);
    136   ans=max(ans,zd-zx1);
    137   ans=max(ans,zd2-zx);
    138   return ans;
    139 }
    140 int main()
    141 {
    142   int x,y,qes;
    143   scanf("%d",&n);
    144   for(int i=1;i<=n;i++) scanf("%d",&dis[i]);
    145   for(int i=1;i<n;i++)
    146     scanf("%d%d",&x,&y),add(x,y),add(y,x);
    147   scanf("%d",&qes);
    148   dad[1]=1,top[1]=1;
    149   dfs1(1,0);dfs2(1,0);
    150   build(1,1,n);
    151   for(int i=1;i<=qes;i++){
    152     int type;
    153     scanf("%d%d%d",&type,&x,&y);
    154     if(type)
    155       printf("%d
    ",solve(x,y));
    156       else change(1,1,n,dfn[x],y);
    157   }
    158   return 0;
    159 }
    
    
    





  • 相关阅读:
    02-单臂路由实验
    线程高级篇-读写锁ReentrantReadWriteLock
    线程高级篇-Lock锁和Condition条件
    002 flutter的路由管理--命名路由
    fluuter的路由管理--普通路由
    003 文档的操作
    002 索引的操作
    001 elasticsearch的核心概念
    002 使用nacos完成服务的注册和发现
    001 Nacos的基础内容
  • 原文地址:https://www.cnblogs.com/pantakill/p/6708369.html
Copyright © 2011-2022 走看看