题解 - 等差数列

题目描述

等差数列 指从第二项起,每一项与它的前一项的差等于同一个常数的一种数列,且这个常数叫做等差数列的公差
例如:数列 15913 就是一个公差为4的等差数列。
现给定一个长度为 n 的序列 a1,a2,….,an,
请问该序列中,有多少个长度不小于 3 的子段满足等差数列?
输入格式
输入共两行
第一行,一个正整数 n,表示给定序列长度
第二行,n 个整数,分别表示序列的每一项 a1,a2,…, an
输出格式
输出一个整数,表示满足条件的子段个数。
数据范围
。对于 30% 的数据,1<n< 100
。对于 60% 的数据,1<n< 104
。对于 100% 的数据,1<n< 105,-10°< a < 109
样例数据
输入:
10
-1 1 3 3 3 2 3 2 1 0
输出:
5
说明:
区间[1,3],[3,5],[7,10],[7,9],[8,10]均满足等差数列要求

分析

知识点:组合数学,贪心,数学

解题思路:

考虑每次找最长的一段使公差 ppp 相等,设这一段的长度为 lenlenlen ,那么这一段的区间数为len×(len−1)2\frac{len \times (len-1)}{2}2len×(len1) 再减去所有长为 2 的区间数 len−1len-1len1 即得合法方案数

考虑 p 不等的时候 ,新等比数列只能从 i-1 位置开始

复杂度 O(n)O(n)O(n)

代码

#include<bits/stdc++.h>
#define LL long long
using namespace std;
int const N=1e5+10;
LL n,m,ans,a[N];
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	int l=1,p=a[2]-a[1];
	for(int i=3;i<=n;i++){
		if(a[i]-a[i-1]!=p){
			LL len=i-l;
			if(len*(len-1)>=6) ans+=len*(len-1)/2-len+1;
			l=i-1; p=a[i]-a[i-1];
		}
	}
	LL len=n-l+1;
	if(len*(len-1)>=6) ans+=len*(len-1)/2-len+1;
	printf("%lld",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值