题面
题目描述
输入
从文件point.in中读入数据
第一行一个整数n
第二行n个整数
a
i
a_i
ai
输出
样例输入
输入1:
5
4 6 9 3 6
输入2:
30
15 15 3 30 9 30 27 11 5 15 20 110 25 20 30 15 30 15 25 5 10 20 7 7 16 2 7 7 28 7
样例输出
输出1:
1 3
2
输出2:
1 13
9
数据范围
提示
题解
此题题解只有一句话:暴力出奇迹,偏分过样例。
这道题看起来数据范围很大,其实
O
(
n
2
)
O(n^2)
O(n2)的暴力即可通过此题。
先从每个点往左往右搜(以它为 a k a_k ak,然后每个点向左和向右扩展,当遇到一个不能整除自己的点时就break。
tips:
一个小优化:当 n − l e f t i < m a x n-left_i<max n−lefti<max时,可证明其不为最优解,可直接break。
代码
#include<bits/stdc++.h>
using namespace std;
int i,j,n,m,k,l,o,p,a[500005],b[500005],r[500005];
bool bz[500005];
int main()
{
// freopen("point.in","r",stdin);
// freopen("point.out","w",stdout);
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=1;
r[i]=n;
}
int maxi=0,maxn=0;
for (i=1;i<=n;i++)
{
for (j=i-1;j>=1;j--)
{
if (a[j]%a[i]!=0)
{
b[i]=j+1;
break;
}
}
if (n-b[i]<maxi) {r[i]=i;break;}
for (j=i+1;j<=n;j++)
{
if (a[j]%a[i]!=0)
{
r[i]=j-1;
break;
}
}
if (r[i]-b[i]>maxi)
{
maxi=r[i]-b[i];
memset(bz,0,sizeof bz);
bz[b[i]]=1;
maxn=1;
}
else
{
if (r[i]-b[i]==maxi&&bz[b[i]]==0) maxn++,bz[b[i]]=1;
}
}
printf("%d %d\n",maxn,maxi);
memset(bz,0,sizeof bz);
for (i=1;i<=n;i++)
{
if (r[i]-b[i]==maxi&&bz[b[i]]==0)
{
printf("%d ",b[i]),bz[b[i]]=1;
}
}
}