题解 CF1654E Arithmetic Operations
容易发现,题意可以转化为:对于所有公差 ,把序列第 个数修改为 ,最多有多少个相等的数。
当 时,必然不可能相等。因此只要考虑 的情况。
考虑两个数距离为 时,只有 才可能相等。因此,当 比较大的时候,每个数只可能和它后(前)面的 个数相等。且如果 位置与 位置相等, 是可以唯一确定的。
根号分治即可。取阈值为 ,第一部分暴力枚举公差 ,第二部分枚举第一个相等的数以及它后面 个数,复杂度 )。所以当 ,复杂度是 。需要开 大小的桶记录。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(x) memset(x,0,sizeof(x))
#define printYes puts("Yes")
#define printYES puts("YES")
#define printNo puts("No")
#define printNO puts("NO")
#define lowbit(x) (x&(-x))
const ll inf=1000000000000000000;
//const ll mod=998244353;
//const ll mod=1000000007;
const int N=100005,B=321,K=N*B+2*N;
int n,m,ans;
int a[N];
int b[N*B*2+4*N],c[N];
inline int read()
{
int F=1,ANS=0;
char C=getchar();
while (C<'0'||C>'9')
{
if (C=='-') F=-1;
C=getchar();
}
while (C>='0'&&C<='9')
{
ANS=ANS*10+C-'0';
C=getchar();
}
return F*ANS;
}
int main()
{
n=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=-B;i<=B;i++)
{
for (int j=1;j<=n;j++)
{
b[a[j]-i*j+K]++;
ans=max(ans,b[a[j]-i*j+K]);
}
for (int j=1;j<=n;j++)
{
b[a[j]-i*j+K]--;
}
}
for (int i=1;i<=n;i++)
{
int r=min(n,i+B);
for (int j=i+1;j<=r;j++)
{
int det=a[j]-a[i],len=j-i;
if (det%len!=0) continue;
int k=det/len;
b[k+K]++;
ans=max(ans,b[k+K]+1);
}
for (int j=i+1;j<=r;j++)
{
int det=a[j]-a[i],len=j-i;
if (det%len!=0) continue;
int k=det/len;
b[k+K]--;
}
}
cout << n-ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类