zoukankan      html  css  js  c++  java
  • $CH5501$ 环路运输 环形$+$单调队列

    CH

    Description

    在一条环形公路旁均匀地分布着N座仓库,编号为1~N,编号为 i 的仓库与编号为 j 的仓库之间的距离定义为 dist(i,j)=min⁡(|i-j|,N-|i-j|),也就是逆时针或顺时针从 i 到 j 中较近的一种.每座仓库都存有货物,其中编号为 i 的仓库库存量为 Ai.在 i 和 j 两座仓库之间运送货物需要的代价为 Ai+Aj+dist(i,j).求在哪两座仓库之间运送货物需要的代价最大.1≤N≤10^6,1<=Ai<=10^7.

     

    Sol

    断环为链,再复制一段到末尾

    枚举i,我们只需要找到一个在[i-N/2,i-1]之间找到一个j使得(a[j]-j)最大,就求出了当前的最大代价.

    找j当然不能枚举(N的范围就在上面),可以用单调队列维护.

    具体来说,双端单调队列的队头放的是a[j]-j的最大值,以及j值(即它的序号),每次i++,把j超过范围(<i-N/2)的移出队列,把队列里比a[i-1]-(i-1)小的移出队列,再将a[i-1]-(i-1)加入队列,最后取出队头,即使当前a[j]-j的最大值.

    如果关于单调队列的部分不明白,建议做Luogu1886滑动窗口

    至于双端,用deque辣QwQ

    Code

     这题的code还是很好实现的 : ) 好久没有一遍过了QwQ

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #define Rg register
     5 #define il inline
     6 #define go(i,a,b) for(Rg int i=a;i<=b;++i)
     7 using namespace std;
     8 il int read()
     9 {
    10     int x=0,y=1;char c=getchar();
    11     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    12     while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    13     return x*y;
    14 }
    15 const int N=1e6+1;
    16 int n,m,ans,a[N*2];
    17 deque<int>q;
    18 int main()
    19 {
    20     n=read();m=n<<1;
    21     go(i,1,n)a[i]=a[n+i]=read();
    22     go(i,2,m)
    23     {
    24         while(q.size()&&i-q.front()>n/2)q.pop_front();
    25         while(q.size()&&a[i-1]-i>a[q.back()]-q.back())q.pop_back();
    26         q.push_back(i-1);
    27         ans=max(ans,a[i]+i+a[q.front()]-q.front());
    28     }
    29     printf("%d
    ",ans);
    30     return 0;
    31 }
    View Code
    光伴随的阴影
  • 相关阅读:
    多层次子查询的sql执行顺序的问题
    RestTemplate不落地中转文件
    Gitbook从安装到使用【转】
    Linux离线安装依赖包技巧
    CentOS7 配置环境变量断开ssh后失效
    分页查询排序问题
    地图坐标的转换
    FeatureLayer图层的属性查询方式(query的使用方法)
    使用LayerView.effect进行点的高亮显示
    DQL + 排序
  • 原文地址:https://www.cnblogs.com/forward777/p/11014754.html
Copyright © 2011-2022 走看看