D. Two Arithmetic Progressions

两数列交集计数
本文介绍一种算法,用于解决两个等差数列在指定范围内共有多少整数交集的问题。通过求解特定的线性方程组找到首个公共元素,并计算在给定区间内的交集数量。

You are given two arithmetic progressions: a1k + b1 and a2l + b2. Find the number of integers x such that L ≤ x ≤ R and x = a1k’ + b1 = a2l’ + b2, for some integers k’, l’ ≥ 0.
Input

The only line contains six integers a1, b1, a2, b2, L, R (0 < a1, a2 ≤ 2·109,  - 2·109 ≤ b1, b2, L, R ≤ 2·109, L ≤ R).
Output

Print the desired number of integers x.
题意: x = a1k’ + b1 = a2l’ + b2, 有L ≤ x ≤ R ,且k’, l’ ≥ 0。问符合条件 的x 有多少个。
a1k- a2l = b2-b1; 求出一组(k,l),并求出第一组解(k0>=0,l0>=0),此时对应一个最小的x。 通解为 k = k0 + -a2/gcd(a1,-a2)t , 则 x = a1(k0 + -a2/gcd(a1,-a2)*t ) + b1;
可以发现 x增值 为 -a1*a2/gcd(a1,-a2) = lcm(a1,a2),所以求出第一个x点后,在算区间有多少个 lcm就好。

#include <bits\stdc++.h>
using namespace std;
typedef long long LL;

LL ex_gcd(LL a,LL b,LL &x,LL &y){
    if (b==0){
        x=1,y=0;
        return a;
    }
    LL q=ex_gcd(b,a%b,y,x);
    y-=a/b*x;
    return q;
}

void minial(LL& x, LL& y,LL k1, LL k2){
     LL t = x/k1;
     x -= t*k1, y -= t*k2;
     if( x < 0){
        x += k1, y+=k2;
     }
    // cout<<x<<" "<<y<<endl;
     if( y < 0){
        t = y/k2;
        x -= t*k1, y -= t*k2;
        if( y < 0){
        x += k1, y+=k2;
        }  
     }
}
LL cal(LL l, LL r, LL lcm){
    if(l > r) return 0;
    LL ans = (r-l)/lcm + 1;
    return ans;
} 

int main(){
    LL a1,b1,a2,b2,l,r;
    scanf("%lld %lld %lld %lld %lld %lld",&a1,&b1,&a2,&b2,&l,&r);
    LL ans = 0, x, y;
    if(b2 < b1) {
        swap(b2,b1);
        swap(a1,a2);
    }
    LL A = a1, B = -a2 , C= b2-b1;    // a1x - a2y = b2-b1;
    long long gcd = ex_gcd(A,B,x,y);  // Ax + By = C 
    if(gcd < 0){
        gcd = -gcd, x = -x, y = -y;
    }
    if(C%gcd !=0){
        printf("0\n");
        return 0;
    }
    else{
        x = C/gcd*x, y = C/gcd*y; // 一组解
        LL k1 = B/gcd, k2 = A/gcd;
        if(k1<0) k1 = -k1;
        if(k2<0) k2 = -k2;
        minial(x,y,k1,k2);  // 第一组 x>=0 y >=0 的解 
        LL d = a1*x + b1;
        ans = cal(d,r,A*k1) - cal(d,l-1,A*k1);
        printf("%lld\n",ans);
    }
    return 0;
}
### 回答1: 这是Java中的一个异常,意思是需要进行四舍五入。通常是因为进行了除法运算,但结果不能被精确表示为一个整数或小数。解决方法是使用BigDecimal类进行精确计算,或者使用Math.round()方法进行四舍五入。 ### 回答2: java.lang.ArithmeticException: rounding necessary是Java中的一个异常。它表示在进行数值运算时,需要进行舍入操作。在Java中,当进行除法或四舍五入等运算时,如果结果不是一个整数,则需要进行舍入以获得最接近的整数或指定的小数位数。 这个异常通常发生在以下情况下: 1. 当进行除法运算时,如果除数不能整除被除数,则需要进行舍入才能得到结果。如果无法进行舍入操作,就会抛出该异常。 2. 当通过四舍五入方式将一个小数转换为整数或指定小数位数时,如果需要进行舍入操作才能得到结果,则会抛出该异常。 为了解决这个异常,我们可以采取以下措施: 1. 检查除法运算中的被除数和除数,确保能够整除,避免出现舍入错误。如果无法整除,则需要重新设计算法或找到其他解决方案。 2. 在进行四舍五入运算时,可以使用Java中的Math类提供的方法,如Math.round()来进行舍入操作。此外,还可以考虑使用BigDecimal类来处理精确的小数运算,它提供了很多可以进行舍入操作的方法。 总之,当我们在Java中遇到java.lang.ArithmeticException: rounding necessary异常时,表示在进行数值运算时需要进行舍入操作。要解决这个异常,我们需要检查除法运算中的被除数和除数,以及使用适当的方法进行舍入操作,保证结果的准确性。 ### 回答3: Java.lang.ArithmeticException: rounding necessary 是一个在Java中的异常类型。它表示在进行数值运算时需要进行四舍五入操作。 在进行数值运算时,可能会出现无法准确表示的结果,特别是涉及到浮点数和小数点的运算。由于计算机的内部表示方式有限,无法完美地表示所有的小数和浮点数。这就导致了某些运算结果的尾数部分可能无法精确表示,需要进行四舍五入操作。 当进行一个数值运算时,如果该运算需要进行四舍五入操作以确保结果的准确性,但是没有指示具体的四舍五入策略时,就会抛出 java.lang.ArithmeticException: rounding necessary 异常。 要解决这个异常,可以使用合适的四舍五入策略来确保数值运算的准确性。Java中提供了 BigDecimal 类来处理高精度的数值计算,它可以指定要使用的四舍五入策略。在进行数值运算时,可以使用 BigDecimal 类来处理数值,并指定需要使用的四舍五入策略,从而避免 java.lang.ArithmeticException: rounding necessary 异常的发生。 总之,解决 java.lang.ArithmeticException: rounding necessary 异常的方法是使用 BigDecimal 类来处理数值运算,并指定合适的四舍五入策略。这样可以确保数值运算的准确性,避免出现无法精确表示的结果导致的异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值