• [loj2392]烟花棒


    显然,有以下三个性质(思路):

    1.烟花传递总是在烟花将要燃尽时将烟花恰传给另一个人

    2.烟花不燃烧的人总是向烟花正在燃烧的人靠拢,并且重合后会一直跟着(燃尽时替上)

    3.烟花正在燃烧的人总是向下一个"跟着"的人靠拢(等着不如接上后返回)

    此时,过程完全由"跟着"的顺序决定(思考一下如何决定?),也即以$k$为中心向两侧扩展

    再考虑相对位置,不难发现扩展$x$时,其与烟花正在燃烧的人的距离总是$\begin{cases}a_{x+1}-a_{x}&(x<k)\\a_{x}-a_{x-1}&(x>k)\end{cases}$(与另一侧扩展的人和扩展的顺序均无关),具体可以归纳证明

    二分枚举答案$v$,并维护当前烟花剩余可燃烧时间$t$(初始为$k$),问题即变为:

    有两个队列(依次存储两侧拓展的距离),每次任选一个队列,记其顶部元素为$d$,若$t\ge \frac{d}{2v}$则可以将$t$变为$t-\frac{d}{2v}+k$并删除该顶部元素,判断是否存在一种删除顺序可以删光两个队列

    从两个队列中取出最短的非空前缀满足$\sum (k-\frac{d}{2v})\ge 0$,若可以取该前缀(即要求$t\ge lim$,$lim$可以求出)显然总可以直接取掉,重复此过程(直至均不存在这样的前缀或均无法取)

    若是因后者而结束,显然问题即无解

    若是因前者而结束,即此时两个队列中任意非空前缀和均小于0,不妨先得到最终的$t$并考虑逆过程(即过程中的$k$和$\frac{d}{2v}$交换一下、队列翻转一下),仍可以使用上述贪心

    此时的后缀和即是原来的前缀和取相反数,总大于等于0,也即不会出现"不存在这样的前缀"的情况

    由此,单次判定复杂度为$o(n)$,总复杂度为$o(n\log n)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 #define ll long long
     5 #define fi first
     6 #define se second
     7 int n,t,k,x[N];
     8 vector<int>vl,vr;
     9 vector<pair<ll,ll> >Vl,Vr; 
    10 bool check(int v){
    11     vl.clear(),vr.clear(),Vl.clear(),Vr.clear();
    12     for(int i=k;i>1;i--)vl.push_back(x[i]-x[i-1]);
    13     for(int i=k+1;i<=n;i++)vr.push_back(x[i]-x[i-1]);
    14     
    15     int lst=-1;
    16     ll lim=0,sum=0;
    17     for(int i=0;i<vl.size();i++){
    18         lim=max(lim,vl[i]-sum),sum+=v-vl[i];
    19         if (sum>=0){
    20             Vl.push_back(make_pair(lim,sum));
    21             lim=sum=0,lst=i;
    22         }
    23     }
    24     reverse(vl.begin(),vl.end());
    25     for(int i=0;i<=lst;i++)vl.pop_back();
    26     
    27     lst=-1,lim=sum=0;
    28     for(int i=0;i<vr.size();i++){
    29         lim=max(lim,vr[i]-sum),sum+=v-vr[i];
    30         if (sum>=0){
    31             Vr.push_back(make_pair(lim,sum));
    32             lim=sum=0,lst=i;
    33         }
    34     }
    35     reverse(vr.begin(),vr.end());
    36     for(int i=0;i<=lst;i++)vr.pop_back();
    37     
    38     ll ans=v;
    39     for(int i=0,j=0;(i<Vl.size())||(j<Vr.size());)
    40         if ((i<Vl.size())&&(Vl[i].fi<=ans))ans+=Vl[i++].se;
    41         else{
    42             if ((j<Vr.size())&&(Vr[j].fi<=ans))ans+=Vr[j++].se;
    43             else return 0;
    44         }
    45     for(int i=0;i<vl.size();i++)ans+=v-vl[i];
    46     for(int i=0;i<vr.size();i++)ans+=v-vr[i];
    47     if (ans<0)return 0;
    48     
    49     Vl.clear(),Vr.clear();
    50     lst=-1,lim=sum=0;
    51     for(int i=0;i<vl.size();i++){
    52         lim=max(lim,v-sum),sum+=vl[i]-v;
    53         if (sum>=0){
    54             Vl.push_back(make_pair(lim,sum));
    55             lim=sum=0,lst=i;
    56         }
    57     }
    58     
    59     lst=-1,lim=sum=0;
    60     for(int i=0;i<vr.size();i++){
    61         lim=max(lim,v-sum),sum+=vr[i]-v;
    62         if (sum>=0){
    63             Vr.push_back(make_pair(lim,sum));
    64             lim=sum=0,lst=i;
    65         }
    66     }
    67     
    68     for(int i=0,j=0;(i<Vl.size())||(j<Vr.size());)
    69         if ((i<Vl.size())&&(Vl[i].fi<=ans))ans+=Vl[i++].se;
    70         else{
    71             if ((j<Vr.size())&&(Vr[j].fi<=ans))ans+=Vr[j++].se;
    72             else return 0;
    73         }
    74     return 1;
    75 }
    76 int main(){
    77     scanf("%d%d%d",&n,&k,&t),t<<=1;
    78     for(int i=1;i<=n;i++)scanf("%d",&x[i]);
    79     if (x[n]==0){
    80         printf("0\n");
    81         return 0;
    82     }
    83     int l=0,r=(x[n]-1)/t+1;
    84     while (l<r){
    85         int mid=(l+r>>1);
    86         if (check(mid*t))r=mid;
    87         else l=mid+1;
    88     }
    89     printf("%d\n",l);
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    mariadb配置双主多从
    mq系列rabbitmq-02集群+高可用配置
    mq系列rabbitmq-01简介,安装,api操作
    持续集成框架jenkins介绍02-持久集成git仓库+maven项目
    git仓库相关知识03-搭建远程仓库服务器
    RecyclerView瀑布流优化方案探讨
    Android实际开发bug大总结
    Android打造万能自定义阴影控件
    PagerAdapter深度解析和实践优化
    Java博客大汇总
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15544471.html
Copyright © 2020-2023  润新知