UOJ#245. 【UER #7】天路

跳蚤国面临寒冬挑战,需启动热能塔抵御严寒。面对敌方的进攻,跳蚤们利用新型材料保护热能塔,通过算法确定最佳防护区间,确保热能塔安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

隆冬将至,几天后跳蚤国便会迎来寒冬,这对于以血肉之躯和飞机搏斗的跳蚤们来说并不是件好事……然而在悠悠历史岁月中,跳蚤国早已有了应对严寒的应急措施方案!

在跳蚤国王的带领下,跳蚤们准备启动天路热能塔 —— 红米 note7(红米 note7 为发烧而生)。这座热能塔高耸入云,直接穿出大气层从太空中直接吸收太阳光,垂直向下将热能送往跳蚤国各个角落。热能塔的制造工艺巧夺天工,被誉为“带来温暖的天路”。

但是跳晚们为了让跳蚤们都因为天气寒冷赖在被子里不肯起床,在热能塔启动后一定会歇斯底里地进攻。跳蚤国高级间谍的情报显示,跳晚国计划将发射 n 台三星 note7 向热能塔发起进攻。进攻将会按一定顺序进行,其中第 i 次进攻的高度为 ai 1in )。

为了防止热能塔被炸毁,跳蚤国王特地派尛焱轟(一种新型交通工具,运载能力是小火车的三次幂)运送来了跳蚤们刚研制出不久的新型材料 —— Nokia1050。跳蚤们将会把 Nokia1050 装在热能塔上的某一连续的高度区间上以抵挡进攻。

现在,跳蚤国王想在热能塔受损程度和材料消耗量之间进行取舍。所以对于每个 2kn ,跳蚤国王想知道整个攻击过程中如果想让 Nokia1050 在某一时段至少挡住连续 k 次攻击,那么安装 Nokia1050 的高度区间的长度至少是多少。其中,若高度区间为 [l,r],则长度为 rl

事实上,间谍的消息也不见得会多么靠谱,所以跳蚤国王仅想知道一个不那么准确的答案。具体来说:

如果对于每个 k 你输出的答案 ck 与标准答案 c^k 的相对误差均不超过 5% ,则算作正确。即:

ckc^k5%c^k

输入格式

第一行一个正整数 n ,保证 n2

第二行 n 个正整数 a1,,an,按顺序给出每次进攻时三星 note7 的高度。

输出格式

输出 n1 行,其中第 k1 行表示至少抵挡连续 k 次攻击时所需的最短高度区间长度。(2kn

因为十分重要所以说两遍,如果对于每个 k 你输出的答案 ck 与标准答案 c^k 的相对误差均不超过 5% ,则算作正确。即:

ckc^k5%c^k

样例一

input
4
1 7 5 2
output
2
5
6
explanation

k=2 时,最优高度区间为 [5,7]

k=3 时,最优高度区间为 [2,7]

k=4 时,最优高度区间为 [1,7]

注意 k=2 时不能选择高度区间 [1,2] ,虽然能够拦截下第 1 次和第 4 次攻击,但这两次攻击并不连续。

样例二

input
10
26 723 970 13 422 968 875 329 234 983
output
93
546
639
734
749
957
957
957
970
explanation

样例输出给出的为准确答案,注意下面的输出也是可接受的:

93
540
630
730
740
960
960
960
970

样例三

见样例数据下载。

限制与约定

测试点编号 n 的规模 特殊限制
1n100 ai100
2
3
4 n1000
5
6 n105 每个 ai 均是从 [1,106] 中独立选取的均匀随机整数
7
8
9
10

对于所有数据,保证 1ai106

时间限制: 1s

空间限制: 256MB

后记

最后跳蚤国保住了热能塔,并且跳蚤国王发现,进入隆冬之后跳晚国的轰炸次数变得越来越少了。原来,不适应在严寒中作战的跳晚国士兵惧怕寒冷变得越来越晚起床了。

“是时候展开反攻了!”


题目大意:给定一个序列, ans[K] 表示 MIN[i,j]K[i,j][i,j] ,求出ans[2..n],注意答案有5%波动范围。


我果然是太弱了,比赛的时候只会骗分。官方题解
总体来说这个idea真的不错,我一直再往随机化等具有不确定性的算法上考虑,但实际上5%的波动范围真正的作用是使得答案合法取值得以减少。
随着区间长度的递增,答案显然是单增的(因为最大值随区间长度不降,最小值随区间长度不增),而“相对误差不超过5%,则算作正确”为我们提供了便利,对于某一个答案我们可以找到一个区间使得这个区间中答案都为这个数但是仍保证合法。
我们考虑枚举答案然后在它的可接受区间内更新答案,这样的话我们每次用两个队列和头尾指针来扫一遍整个区间,若是当前头尾指针间的最大值-最小值大于当前枚举的答案就考虑将头指针前移来把最大值和最小值不断弹出直到可以接受,然后更新答案就好了。
而我们显然是不能枚举 106 中答案的,考虑到波动范围为5%,所以我们只枚举 1.05x 的答案就好了,因为这些权值的可接受区间是准确的,那么对应到区间上来说就能保证答案都合法了。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define INF 2147483647
using namespace std;
const int N=100100;
int n,mx1,mx2,a[N],ans[N];
int q1[N],h1,t1;
int q2[N],h2,t2;
int main()
{
    scanf("%d",&n);mx1=INF;
    for (int i=1;i<=n;++i)
    {
        scanf("%d",a+i);
        mx1=min(mx1,a[i]);
        mx2=max(mx2,a[i]);
    }
    memset(ans,127,sizeof(ans));
    for (int now=0;now<=mx2-mx1+1000000;now=max(now+1,(int)(now*1.05)))
    {
        h1=h2=1;q1[t1=1]=q2[t2=1]=1;
        for (int j=1,i=2;i<=n;++i)
        {
            while(h1<=t1&&a[q1[t1]]<a[i])--t1;
            while(h2<=t2&&a[q2[t2]]>a[i])--t2;
            q1[++t1]=i;q2[++t2]=i;
            while(a[q1[h1]]-a[q2[h2]]>now)
            {
                if(q1[h1]==j)++h1;
                if(q2[h2]==j)++h2;
                ++j;
            }
            ans[i-j+1]=min(ans[i-j+1],a[q1[h1]]-a[q2[h2]]);
        }
    }
    for (int i=n-1;i>=2;--i)ans[i]=min(ans[i],ans[i+1]);
    for (int i=2;i<=n;++i)printf("%d\n",ans[i]);
    return 0;
}

总结:
1、什么元素有特殊性就要优先想一想能不能从这个方面入手解决问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值