zoukankan      html  css  js  c++  java
  • 题解 CF515E 【Drazil and Park】

    思路:

    (quad)对于此题考虑使用线段树维护,因为有环,所以断环为链,数组开两倍,另外距离换成坐标(距离的前缀和),假设最后求的两棵树分别为 (x)(y) ((dis_x<dis_y)),那么答案就是 (2 imes (h_x+h_y)+dis_y-dis_x) ,就是 ((2 imes h_x-dis_x)+(2 imes h_y+dis_y)) ,那么我们线段树维护这两个值及答案,一个作答案的左端点( (x) ),一个作答案的右端点( (y) ),注意要保证 (dis_x<dis_y) ,建树和询问的代码应重点看看,另外询问返回的值是结构体,数值初始化应为 (-inf) ,因为 (sumr) 的值可能为负,时间复杂度为 (O((n+m)log {2n}))

    struct node{
      int suml,sumr,Max;
    }t[N<<2];
    il void build(int k,int l,int r)
    {
      if(l==r){t[k].suml=h[l]+dis[l];t[k].sumr=h[l]-dis[l];t[k].Max=-inf;return;}//suml表示作右端点,sumr表示作左端点
      int mid=l+r>>1;
      build(k<<1,l,mid);build(k<<1|1,mid+1,r);
      t[k].suml=max(t[k<<1].suml,t[k<<1|1].suml);
      t[k].sumr=max(t[k<<1].sumr,t[k<<1|1].sumr);
      t[k].Max=max(t[k<<1].Max,max(t[k<<1|1].Max,t[k<<1|1].suml+t[k<<1].sumr));//取 (左儿子的最大值,右儿子的最大值,左儿子中最适合作左端点的加上右儿子中最适合作右端点的和) 这三者的最大值 
    }
    il node query(int k,int l,int r,int x,int y)
    {
      if(x<=l&&y>=r)return t[k];
      int mid=l+r>>1;node t1,t2,t3;
      t1.suml=t1.sumr=t1.Max=t2.suml=t2.sumr=t2.Max=t3.suml=t3.sumr=t3.Max=-inf;
      if(x<=mid)t1=query(k<<1,l,mid,x,y);
      if(y>mid)t2=query(k<<1|1,mid+1,r,x,y);
      t3.suml=max(t1.suml,t2.suml);
      t3.sumr=max(t1.sumr,t2.sumr);
      t3.Max=max(t1.Max,max(t2.Max,t2.suml+t1.sumr));
      return t3;
    }
    

    (quad)关于变量名的解释:用数组 (h_i) 表示第 (i) 棵树的高度(或 (i-n) ),数组 (d_i) 表示第 (i) 棵树和第 (i+1) 棵树的距离,数组 (dis_i) 表示第 (i) 棵树的坐标, (sumr) 指最大的可做左端点的数, (suml) 指最大的可做右端点的数, (Max) 指这个区间的最大答案

    (quad)再看看主函数吧,求补集的操作要额外注意

    signed main()
    {
      n=read();m=read();
      for(re i=1;i<=n;i++)d[i]=d[i+n]=read();
      for(re i=1;i<=n;i++)h[i]=h[i+n]=read()<<1;
      for(re i=1;i<=n<<1;i++)dis[i]=dis[i-1]+d[i-1];//注意d[i-1]表示的才是第i-1棵树与第i棵树的距离
      build(1,1,n<<1);//建树
      while(m--)
        {
          re x=read(),y=read();
          if(y<x){swap(x,y);x++;y--;}  //这个求补集的操作也要额外注意
          else {swap(x,y);x++;y=y+n-1;}//这个求补集的操作也要额外注意
          print(query(1,1,n<<1,x,y).Max);putchar('
    ');
        }
      return 0;
    }
    
  • 相关阅读:
    [LeetCode] Word Ladder II
    [LeetCode] Edit Distance
    [LeetCode] Merge Intervals
    内存分配与Segmentation fault
    结构体 指针 数组
    resolv.conf
    无法启动xwindow
    stopping NetworkManager daemon failed
    linux 挂载光盘:mount: you must specify the filesystem type
    修改主机hostname
  • 原文地址:https://www.cnblogs.com/FarkasW/p/14027425.html
Copyright © 2011-2022 走看看