【NOIP2014模拟10.26】数字对

本文探讨了一种寻找序列中特殊区间的方法,通过定义特殊区间及其价值,提出了一个算法来找到序列中所有特殊区间的最大价值及对应的区间数量,同时给出了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.

 

题解:

暴力打标记。

易证:O(n)

#include<bits/stdc++.h>
#define N 500010
#define inf 2147483647
#define rint register int
#define ll long long
#define point(a) multiset<a>::iterator 
#define mod (ll)(500000)
#define mem(a,b) memset(a,b,sizeof (a))
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;

struct interval
{
	int x,y;
}s[N];

int n,ans,i;
int bz[N],l,r,a[N],num,flag[N];
void right_updata()
{
	while(r<n && a[r+1] % a[i] == 0)++r,bz[r]=i; }
	
void left_updata(int k)
{
	while(l>1 && a[l-1] % a[i] == 0)--l; 
}
int main()
{
	open("number");
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d",&a[i]);
	mem(bz,0);
	for(i=1;i<=n;++i)
	if(!bz[i])
	{
		l=r=i;
		right_updata();
		//确定r 
		left_updata(a[i]);
		//确定l,更新前面的区间. 
		s[i].x=l,s[i].y=r,bz[i]=i;
	}
	ans=0;
	for(i=1;i<=n;i++)ans=max(ans,s[i].y -s[i].x);
	
	for(mem(flag,0),i=1;i<=n;i++)if(ans == s[i].y-s[i].x && !flag[s[i].x])	++num,flag[s[i].x]=1;
	
	printf("%d %d\n",num,ans);
	
	for(mem(flag,0),i=1;i<=n;i++)if(ans == s[i].y - s[i].x && !flag[s[i].x]) printf("%d ",s[i].x),flag[s[i].x]=1;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值