【题解】A23329.等差数列计数

题目链接:等差数列计数

题目描述

首先根据题目要求,给定一个等差数列的首项 t1 和这个等差数列的末项 tn,问符合这个形式的等差数列的数量。

例如,对于第一个 Testcase,当 t11tn9 时,可行的等差数列方案数有四个,分别为以下所示:

  1. S={1,2,3,4,5,6,7,8,9}
  2. S={1,3,5,7,9}
  3. S={1,5,9}
  4. S={1,9}

思路分析

我们知道,等差数列的公差数量就是这个等差数列的可行方案数,即有多少种不同的公差方案,就可以构造出多少种不同的等差数列。因此通过分析题意,我们可以将问题更细致地转换为 已知等差数列的首项和尾项,求出这个等差数列公差的可行方案数。所以对于本题而言,我们只需要求出有多少个公差就可以了。

显然本题的就引刃而解了,我们只需要求出这个等差数列首项和末项的差的绝对值,即 diff=|tnt1|。然后我们只需要求出 diff 的因数个数即可。diff 的因数就是可行的因数方案(详细证明过程见下文)。

例如,当 t11tn9 时,diff=|91|=88 的因数有四个,分别是 {1,2,4,8},因此当这个等差数列首项为 1,末项为 9 时,可行的等差数列方案应为四个。

结论证明

通过等差数列公式,我们可以将等差数列的首项和末项通过公式联立起来,得到 tn=t1+(n1)×d,其中 n 表示等差数列的项数,d 表示等差数列的公差。

由于我们想要求解所有的因数个数,因此我们将通过移项的操作将 d 放到等式左边,将其余的量都放到等式右边。得到:

(1)tnt1=(n1)×dd=tnt1n1

由于等差数列的性质,n1 必须为非负整数(等差数列的长度不能 0)。或者根据等差数列的另一个性质,如果首项和末项的差为负数,那么公差也必须为负数,反之亦然。因此也可以推导出 n1 必须是非负整数。

为了方便起见,我们将 n1 看作为一个整体,另 Δt=n1。将该整体代入方程后即可得到 d=tnt1Δt。为了使 d 是一个整数,因此 tnt1 必须是 Δt 的倍数。因此我们只需要通过枚举上述方程,计算 tnt1 所有的因数数量就可以得到本问题的解。

AC 代码

以下是本题的 AC 代码。需要注意的是,由于本题的数据量比较大,因此在判断因数的过程中需要优化算法(与判断质数类似),这样子算法就可以在 O(n) 的时间内完成枚举,不至于超时:

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

int t, a, b;

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> t;
    while(t--){
        cin >> a >> b;
        int change = abs(b - a), cnt = 0;
        for (int i=1; i*i<=change; i++){
            if (change % i == 0){
                if (i*i != change) cnt += 2;
                else cnt += 1;
            }
        }
        cout << cnt << endl;
    }
    return 0;
}
posted @   Macw  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示