等差数列问题——数学推导

142 篇文章 0 订阅
73 篇文章 0 订阅

题目: https://www.luogu.org/problemnew/show/P1147
题解
数据规模在百万级别,用两个for循环嵌套一定会超时
方法一:数论分析
设首项为L,末项为R,那么sum(L,R)=(L+R)(R-L+1)/2=M
即(L+R)(R-L+1)=2M
可以把2M分解成两个数之积,假设分成了两个数K1,K2,且K1<K2时,
可以列一个二元一次方程组
R-L+1=K1 L+R=K2 解得L=(K2-K1+1)/2, R=(K1+K2-1)/2
当K1,K2一奇一偶时,L,R才有自然数解.
不过有一种特殊情况,就是L=R的情况,这种情况是不允许的
即(K2-K1+1)/2≠(K1+K2-1)/2,解得K1≠1

#include<bits/stdc++.h>
using namespace std;
int main(){
	long long m,k,k2,l,r;
	cin>>m;
	m=m<<1;//m乘2 
    k=sqrt(m);
    for(int k1=k;k1>=2;k1--)//i=1时l=r 不符合题意 
    	if(m%k1==0){
		 k2=m/k1;
		if((k2-k1)&1==1){
		    l=(k2-k1+1)>>1;
			r=(k2+k1-1)>>1;    
    	    cout<<l<<' '<<r<<endl;
        }
	}
	return 0;
}

在这里插入图片描述
方法二:双指针(尺取法)

#include<bits/stdc++.h>
using namespace std;
int main()
{//尺取法是整体往右走的 
	int i,j,n,m,sum;
	cin>>m;
	n=m>>1;
	i=1,j=2,sum=3;
	while(i<=n)//当i=1时的特殊情况 
	{
		if(sum<m)
		{
			j++;
			sum+=j;
		}
		else if(sum==m)
		{
			cout<<i<<' '<<j<<endl;
			sum-=i;
			i++;
		}
		else 
		{
			sum-=i;
			i++;
		}		
	}
	return 0;
} 

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值