题解 - C F 1364 B \mathrm{CF1364B} CF1364B
题目意思
S o l \mathrm{Sol} Sol
- 首先我们考虑一个性质,如何才能使得贡献尽量大。画几个图看看

对于第一种一条直线类型的它的实际贡献就是 ∣ c − a ∣ |c-a| ∣c−a∣,而对于第二种它的贡献就为 ∣ a − d ∣ + ∣ d − b ∣ + . . . ∣ c − e ∣ |a-d|+|d-b|+...|c-e| ∣a−d∣+∣d−b∣+...∣c−e∣。发现能产生贡献的情况就是那种峰,谷的情况,于是我们记录这些拐点即可。时间复杂度 O ( n ) O(n) O(n)
C o d e \mathrm{Code} Code
#include <bits/stdc++.h>
#define For(i,a,b) for ( int i=(a);i<=(b);i++ )
#define Dow(i,b,a) for ( int i=(b);i>=(a);i-- )
#define GO(i,x) for ( int i=head[x];i;i=e[i].nex )
#define mem(x,s) memset(x,s,sizeof(x))
#define cpy(x,s) memcpy(x,s,sizeof(x))
#define YES return puts("YES"),0
#define NO return puts("NO"),0
#define GG return puts("-1"),0
#define pb push_back
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int mod=1e9+7;
const int mo=998244353;
const int N=1e5+5;
int n,m,Q,a[N],b[N],ans;
int main()
{
Q=read();
For(q,1,Q)
{
n=read();
For(i,1,n) a[i]=read();
b[m=1]=1;
For(i,2,n-1)
if((a[i]>a[i-1]&&a[i]>a[i+1])||(a[i]<a[i-1]&&a[i]<a[i+1])) b[++m]=i;
b[++m]=n;
printf("%d\n",m);
For(i,1,m) printf("%d ",a[b[i]]);
puts("");
}
return 0;
}

博客详细解析了CF1364B问题,探讨了如何找到最大社交距离子序列的方法。通过分析贡献最大化的情况,指出关键在于找到序列中的拐点,时间复杂度为O(n)。
3132

被折叠的 条评论
为什么被折叠?



