P14058【MX-X21-T3】[IAMOI R5] 两个人的演唱会
P14058 【MX-X21-T3】[IAMOI R5] 两个人的演唱会
https://www.luogu.com.cn/problem/P14058
题目背景
许多年之后,她站在璀璨的舞台上,望着底下汹涌的粉丝,却失神了片刻——
在漫长的追梦路上,她总会想起那道信任的目光,和自己的第一场「演唱会」。
没有绚丽的灯光,没有华美的妆造,有的只是一个孩子为了鼓励另一个孩子追求梦想而搭建起的舞台。
题目描述
知更鸟有一个长度为 \(n\) 的,由正整数组成的环 \(a_1, \ldots, a_n\),她要你将这个环切成若干段,使得所有段的段内极差都小于等于 \(m\),求分成的最小段数。
输入格式
本题有多组测试数据。
输入的第一行包含一个整数 \(T\),表示测试数据的组数。
接下来包含 \(T\) 组数据,对于每组数据:
-
第一行包含两个正整数 \(n,m\)。
-
第二行包含 \(n\) 个正整数 \(a_1\sim a_n\)。
输出格式
对于每组数据输出一行包含一个整数,表示答案。
输入输出样例 #1
输入 #1
3
5 5
4 1 10 6 7
6 138
1 3 8 98 40 138
6 38
1 3 8 98 40 138
输出 #1
2
1
4
说明/提示
【样例解释】
对于第一组数据,把这个环切成 \(2\) 段,第一段上的数为 \(4,1\),第二段上的数为 \(10,6,7\),每段的极差都不超过 \(5\),可以证明不存在段数更少的划分方案,答案为 \(2\)。
对于第二组数据,可以不切这个环,可以证明不存在段数更少的划分方案,答案为 \(1\)。
对于第三组数据,把这个环切成 \(4\) 段,第一段上的数为 \(1,3,8\),第二段上的数为 \(98\),第三段上的数为 \(40\),第四段上的数为 \(138\),每段的极差都不超过 \(38\),可以证明不存在段数更少的划分方案,答案为 \(4\)。
【数据范围】
本题采用捆绑测试。
记 \(\sum n\) 表示单个测试点中 \(n\) 的和。
| \(\text{Subtask}\) | \(\sum n\le\) | 特殊性质 | 分数 |
|---|---|---|---|
| \(1\) | \(20\) | 无 | \(11\) |
| \(2\) | \(500\) | 无 | \(5\) |
| \(3\) | \(5000\) | 无 | \(13\) |
| \(4\) | \(3\times 10^5\) | 无 | \(19\) |
| \(5\) | \(1.5\times 10^6\) | 无 | \(17\) |
| \(6\) | \(3\times 10^7\) | A | \(5\) |
| \(7\) | \(3\times 10^7\) | B | \(11\) |
| \(8\) | \(3 \times 10^7\) | 无 | \(19\) |
-
特殊性质 A:\(\forall i\in[1,n],a_i\le 2\)。
-
特殊性质 B:\(a_1-a_n>m\)。
对于所有数据,保证 \(1\le T\le 5\times10^6\),\(1 \le n,\sum n\le 3 \times 10^7\),\(1 \le m,a_i \le 10^9\)。
【提示】
数据输入输出的规模可能较大,请选手注意输入读取和输出方式的效率。请注意本题特别的时空限制。
题解
贪心的取一个最小值所包含的区间断开,接着能接就接否则就断开。
#include<bits/stdc++.h>
#define wk(x) write(x),putchar(' ')
#define wh(x) write(x),putchar('\n')
#define N 100000005
#define int long long
using namespace std;
int n,m,k,jk,ans,sum,num,cnt,tot;
int dis[N],vis[N];
int read(int &x){
x=0;int ff=1;char ch=getchar();
while(!(ch>='0'&&ch<='9')){ff=(ch=='-'?-1:ff);ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
x*=ff;return x;
}
void write(int x){
if(x<0){x=-x;putchar('-');}
if(x>=10) write(x/10);
putchar('0'+(x%10));return;
}
signed main(){
read(jk);while(jk--){
read(n),read(m);ans=2e9;tot=0;
for(int i=1;i<=n;i++){
read(dis[i]);dis[i+n]=dis[i+2*n]=dis[i];
ans=min(ans,dis[i]);tot=max(tot,dis[i]);
}int l,r;
if(tot-ans<=m){
wh(1);
continue;
}
for(int i=n+1;i<=2*n;i++){
if(dis[i]==ans){
l=i;r=i;
break;
}
}int x=0,y=0,z=l;cnt=0;
while(x<n&&dis[l-1]-ans<=m) l--,x++;
while(x+y<n&&dis[r+1]-ans<=m) r++,y++;
for(int i=r+1;i<r+n-x-y;i++) vis[++cnt]=dis[i];
int mx=0,mn=2e9;sum=0;
for(int i=1;i<=cnt;i++){
mx=max(mx,vis[i]);mn=min(mn,vis[i]);
if(mx-mn>m){
mx=mn=vis[i];
sum++;//printf("|");
}//wk(vis[i]);
// if(mx==mn&&mn==vis[i])
// printf("|");
}wh(sum+2);
}
return 0;
}
本文来自博客园,作者:Red_river_hzh,转载请注明原文链接:https://www.cnblogs.com/Red-river-hzh/p/19276901

浙公网安备 33010602011771号