打卡信奥刷题(3513)用C++实现信奥题 P10878 [JRKSJ R9] 在相思树下 III

P10878 [JRKSJ R9] 在相思树下 III

题目背景

我知

再迷恋他也非我能私有

就当神爱世人遥远温柔

未必要牵手

隔千万光年宇宙献吻

亦真切感受

不用

强求

对号入座那虚构

题目描述

给你一个长为 nnn 的序列 a1…na_{1\dots n}a1n,你需要对它进行两种操作共 n−1n-1n1 次。

对一个长度为 lll 的序列 b1…lb_{1\dots l}b1l 进行一次操作将会把序列变为一个长为 l−1l-1l1 的序列 c1…l−1c_{1\dots l-1}c1l1

  • 操作一中,∀i∈[1,l),ci=max⁡(bi,bi+1)\forall i\in[1,l),c_i=\max(b_i,b_{i+1})i[1,l),ci=max(bi,bi+1)
  • 操作二中,∀i∈[1,l),ci=min⁡(bi,bi+1)\forall i\in[1,l),c_i=\min(b_i,b_{i+1})i[1,l),ci=min(bi,bi+1)

给定整数 mmm,你只能进行至多 mmm 次操作一。进行 n−1n-1n1 次操作后序列 aaa 的长度变为 111。你可以任意安排操作的顺序,求最终剩余的数 a1a_1a1 的最大值。

输入格式

第一行两个整数 n,mn,mn,m

第二行 nnn 个整数 aia_iai 表示初始序列。

输出格式

一个整数,代表最终剩余的数的最大可能值。

输入输出样例 #1

输入 #1

4 2
1 2 3 3

输出 #1

3

说明/提示

样例解释

一种可能的操作顺序是:

  • 进行一次操作一,序列变为 2,3,32,3,32,3,3
  • 进行一次操作二,序列变为 2,32,32,3
  • 进行一次操作一,序列变为 333

显然最终剩余的数不可能大于 333

数据规模与约定

本题采用捆绑测试。

Subtask\mathrm{Subtask}Subtaskn≤n\len特殊性质分数
111101010101010
222500050005000303030
33310610^6106✓\checkmark202020
44410610^6106404040

特殊性质:保证 ∀i∈[1,n],ai≤10\forall i\in[1,n],a_i\le10i[1,n],ai10

对于所有数据,保证 1≤m<n≤1061\leq m < n \leq 10^61m<n1061≤ai≤1091 \leq a_i \leq 10^{9}1ai109

C++实现

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,ans=LLONG_MAX;
int a[1000005],b[1000005];
struct node{
	int l,r,sum1;
}tree[4000005];
void upd(int now){
    tree[now].sum1=max(tree[now<<1].sum1,tree[now<<1|1].sum1);
}
void build(int now,int l,int r){
    tree[now].l=l;
	tree[now].r=r;
	if(l==r){
        tree[now].sum1=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(now<<1,l,mid);
	build(now<<1|1,mid+1,r);
	upd(now);
}
int search1(int now,int l,int r){
	if(tree[now].l>=l&&tree[now].r<=r) return tree[now].sum1;
	int mid=(tree[now].l+tree[now].r)>>1;
	if(r<=mid) return search1(now<<1,l,r);
	else if(l>mid) return search1(now<<1|1,l,r);
	else return max(search1(now<<1,l,mid),search1(now<<1|1,mid+1,r));
}
signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    build(1,1,n);
    for(int i=1;i<=n-m;i++){
        b[i]=search1(1,i,i+m);
        ans=min(ans,b[i]);
    }
    printf("%lld",ans);
    return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值