Lost Arithmetic Progression
题意:
给出两个等差数列b和c,c是另一个等差数列a和b的公共部分。给出b,c的首相,公差和项数。
求满足条件的a数列的方案数。如果有无限个a满足条件,输出-1,如果没有,输出0。
思路:
设b数列的首项,公差,项数为a1,d1,n1,c数列为a2,d2,n2.
先考虑输出0的情况:
d2 % d1 != 0 || a2 < a1 || (a2 - a1) % d1 != 0 || a2 + (n2 - 1) * d2 > a1 + (n1 - 1) * d1
再考虑输出-1的情况:
如果a1大于a2-d2的话,那么a数列就可以向左边无限延申,如果a1 + (n1 - 1) * d1小于a2 + (n2 - 1) * d2 + d2的话,a就可以往右边无限延申。
a1 > a2 - d2 || a1 + (n1 - 1) * d1 < a2 + (n2 - 1) * d2 + d2
最后考虑一般情况:
因为c是a和b的公共部分,设a的首项,公差,项数为a3,d3,n3,则lcm(d1,d3)== d2。
我们可以枚举a数列的公差d3,对于每一个d3,a数列可以向左右分别延申d2/d3个元素,所以方案数为(d2/d3)*(d2/d3)。
代码:
/*************************************************************************
> File Name: c.cpp
> Author: Beans
> Mail: 3112748286@qq.com
> Created Time: 2023/5/12 17:14:15
************************************************************************/
#include <iostream>
#include <algorithm>
#define int long long
#define endl '\n'
using namespace std;
const int maxn = 3e5 + 7;
const int mod = 1e9 + 7;
int t, a1, d1, n1, a2, d2, n2;
int gcd(int a, int b){
return b ? gcd(b, a % b) : a;
}
int lcm(int a, int b){
return a / gcd(a, b) * b % mod;
}
void solve(){
cin >> a1 >> d1 >> n1 >> a2 >> d2 >> n2;
if(d2 % d1 != 0 || a2 < a1 || (a2 - a1) % d1 != 0 || a2 + (n2 - 1) * d2 > a1 + (n1 - 1) * d1){
cout << 0 << endl;
return;
}
if(a1 > a2 - d2 || a1 + (n1 - 1) * d1 < a2 + (n2 - 1) * d2 + d2){
cout << -1 << endl;
return;
}
int ans = 0;
for(int i = 1; i * i <= d2; i ++ ){
if(d2 % i == 0){
if(lcm(i, d1) == d2){
ans = (ans + d2 / i * d2 / i) % mod;
}
int y = d2 / i;
if(i * i != d2){
if(lcm(y, d1) == d2){
ans = (ans + d2 / y * d2 / y) % mod;
}
}
}
}
cout << ans << endl;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> t;
while(t -- )
solve();
}