Codeforces Round #731 (Div. 3) E. Air Conditioners思维

 

 

在一条长度为𝑛的狭长土地上有𝑘台空调:𝑖-th空调放置在细胞𝑎𝑖(1≤𝑎𝑖≤𝑛)。两个或更多的空调不能放置在同一个单元(即所有𝑎𝑖是不同的)。

每台空调的特点是一个参数:温度。将“𝑖-th”空调的温度设置为“𝑡𝑖”。

带的长度𝑛= 6,𝑘= 2,𝑎=(2、5)和𝑡=(14、16)。
对于每个单元格𝑖(1≤𝑖≤𝑛)找到它的温度,可以由公式计算min1≤𝑗≤𝑘(𝑡𝑗+ |𝑎𝑗−𝑖|),在那里|𝑎𝑗−𝑖|表示绝对值的区别𝑎𝑗−𝑖。

换句话说,细胞𝑖的温度等于空调温度中的最小值,它与细胞𝑖的距离增加。

让我们看一个例子。假设𝑛=6,𝑘=2,第一个空调放置在单元𝑎1=2中,并设置为温度𝑡1=14,第二个空调放置在单元𝑎2=5中,并设置为温度𝑡2=16。在这种情况下,细胞内的温度为:

温度在细胞1:min(14 + | 2−1 |, 16 + | 5 |−1)= min (14 + 1, 16 + 4) = min (15,20) =15;
温度在细胞2:min(14 + | 2−2 |,16 + | 5 |−2)= min (14 + 0, 16 + 3) = min(14,19)= 14;
温度在细胞3:min(14 + | 2−3 | ,16 + | 5−3 |)= min (14 + 1, 16 + 2) = min(15,18)= 15;
温度在细胞4:min(14 + | 2−4 |,16 + | 5−4 |)= min (14 + 2, 16 + 1) = min(16,17)= 16;
温度在细胞5:min(14 + | 2−5 | ,16 + | 5−5 |)= min (14 + 3, 16 + 0) = min(17,16)= 16;
温度在细胞6:min(14 + | 2−6 |,16 + | 5−6 |)= min (14 + 4, 16 + 1) = min(18,17)= 17。
对于从1到𝑛的每个单元格,求出其中的温度。

输入
第一行包含一个整数𝑞(1≤𝑞≤104)—输入中的测试用例的数量。然后是测试用例。在每个测试用例之前,有一个空行。

每个测试用例包含三行。第一行包含两个整数𝑛(1≤𝑛≤3⋅105)和𝑘(1≤𝑘≤𝑛),分别是土地的长度和空调的数量。

第二行是𝑘整数𝑎1,𝑎2,…,𝑎𝑘(1≤𝑎𝑖≤𝑛),分别表示空调在条形土地上的位置。

第三行为𝑘整数𝑡1,𝑡2,…,𝑡𝑘(1≤𝑡𝑖≤109)—空调温度。

保证𝑛在所有测试用例上的总和不超过3⋅105。

输出
对于每个测试用例输出𝑛由空格分隔的整数:单元内的空气温度。

例子
inputCopy
5

6 - 2
2个5
14日16

10 1
7
30.

5个5
3 1 4 2 5
3 1 4 2 5

7个1
1
1000000000

6 3
6 1 3
5 5 5
outputCopy
15 14 15 16 16 17
36 35 34 33 32 31 30 31 32 33
1 2 3 4 5
1000000000 1000000001 1000000002 1000000003 1000000004 1000000005 1000000006
5 6 5 6 6 6 5

———————————————————————————————————————————

        先开始看这道题,每次维护当前点的最小值,然后每个空调的值不同。

本能的想起来使用线段树来记录每次修改的值,然后单点修改,再用二分查找,进行区间修改。。。。但感觉太麻烦了,变成了暴力题。

后来一想,每次维护每个点的左右两边的值,直接放点进去,然后正着扫一遍,再倒着扫一遍,就是各个的点的权值最小啦。但是因为可能放空调的会有重复的点,所以我们每次取最小的。

上代码:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long  ll;
int n,t,q;
int a[300005];
int b[300005];
ll ans[300005];
ll min(ll x,ll y){
    if(x<y)
    return x;
    return y;
}
void solv(){
    cin>>n>>q;
    for (int i =0; i<=n; i++) {
        ans[i]=1e17+5;
    }
    for (int i =0; i<q; i++) {
        cin>>a[i];
    }
    for (int i =0; i<q; i++) {
        cin>>b[i];
    }
    for (int i =0; i<q; i++) {
        ans[a[i]]=min(ans[a[i]], b[i]);
    }
    for (int i =1; i<=n; i++) {
        if (ans[i]>ans[i-1]+1) {
            ans[i]=ans[i-1]+1;
        }
    }
    for (int i =n-1; i>0; i--) {
        if (ans[i]>ans[i+1]+1) {
            ans[i]=ans[i+1]+1;
        }
    }
    for (int i =1; i<=n; i++) {
        printf("%lld ",ans[i]);
    }printf("\n");
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>t;
    while (t--) {
        solv();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值