数字对

Description
小H是个善于思考的学生,现在她又在思考一个有关序列的问题。
她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n)。
这个特殊区间满足,存在一个k(L <= k <= R),并且对于任意的i(L <= i <= R),ai都能被ak整除。这样的一个特殊区间 [L, R]价值为R - L。
小H想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢?这些区间又分别是哪些呢?你能帮助她吧。

Input
第一行,一个整数n.
第二行,n个整数,代表ai.

Output
第一行两个整数,num和val,表示价值最大的特殊区间的个数以及最大价值。
第二行num个整数,按升序输出每个价值最大的特殊区间的L.

Sample Input
输入1:
5
4 6 9 3 6
输入2:
5
2 3 5 7 11

Sample Output
输出1:
1 3
2
输出2:
5 0
1 2 3 4 5

Data Constraint
30%: 1 <= n <= 30 , 1 <= ai <= 32.
60%: 1 <= n <= 3000 , 1 <= ai <= 1024.
80%: 1 <= n <= 300000 , 1 <= ai <= 1048576.
100%: 1 <= n <= 500000 , 1 <= ai < 2 ^ 31.

.
.
.
.
.
分析
水法真神奇,暴力出奇迹!
在这里插入图片描述
数据太水了,自己出的数据都能把程序卡到80分,结果交上去就AC了

我们暴力枚举每一位为k
以当前位置向左、向右扩展,遇到不合法的就停止
最后判断并统计答案即可

注意,可能会出现长度一样,所在区间也一样,这时就要判重(例如有多个数字为1的情况)
(但这种情况未得到有效的验证,有可能只有1这种情况)

最后要将答案的数组排序输出(以免出现数组不为有序的情况,同时,这种情况未得到有效的验证)

所以你爱打不打

而真正的正解是这样的:
在这里插入图片描述

.
.
.
.
.
程序:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long ansl[500010],ansr[500010],a[500010];
int n;

inline long long read()
{
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}

int main()
{
	n=read();
	for (int i=1;i<=n;i++)
		a[i]=read();
	int num=0,val=0;
	
	for (int i=1;i<=n;i++)
	{
		int l=i,r=i;
		while (a[r+1]%a[i]==0&&r<n) r++;
		while (a[l-1]%a[i]==0&&l>1) l--;
		if (r-l>val)
		{
			val=r-l;
			num=0;
			num++;
			ansl[num]=l;
			ansr[num]=r;
		} else
		if (r-l==val)
		{
			if (ansl[num]!=l||ansr[num]!=r)
			{
				num++;
				ansl[num]=l;
				ansr[num]=r;
			}
		}
	}
	sort(ansl+1,ansl+num+1);
	printf("%d %d\n",num,val);
	for (int i=1;i<=num;i++)
		printf("%lld ",ansl[i]);
	return 0;
}
posted @ 2019-01-25 14:32  银叶草  阅读(224)  评论(0编辑  收藏  举报
Live2D