@@ -102,9 +102,9 @@ pub fn convolution_i64(a: &[i64], b: &[i64]) -> Vec<i64> {
102
102
return vec ! [ ] ;
103
103
}
104
104
105
- let i1 = internal_math:: inv_gcd ( M2M3 as _ , M1 as _ ) . 1 ;
106
- let i2 = internal_math:: inv_gcd ( M1M3 as _ , M2 as _ ) . 1 ;
107
- let i3 = internal_math:: inv_gcd ( M1M2 as _ , M3 as _ ) . 1 ;
105
+ let ( _ , i1 ) = internal_math:: inv_gcd ( M2M3 as _ , M1 as _ ) ;
106
+ let ( _ , i2 ) = internal_math:: inv_gcd ( M1M3 as _ , M2 as _ ) ;
107
+ let ( _ , i3 ) = internal_math:: inv_gcd ( M1M2 as _ , M3 as _ ) ;
108
108
109
109
let c1 = convolution_raw :: < i64 , M1 > ( a, b) ;
110
110
let c2 = convolution_raw :: < i64 , M2 > ( a, b) ;
@@ -116,10 +116,11 @@ pub fn convolution_i64(a: &[i64], b: &[i64]) -> Vec<i64> {
116
116
. map ( |( ( c1, c2) , c3) | {
117
117
const OFFSET : & [ u64 ] = & [ 0 , 0 , M1M2M3 , 2 * M1M2M3 , 3 * M1M2M3 ] ;
118
118
119
- let mut x = 0 ;
120
- x += ( c1 * i1) . rem_euclid ( M1 as _ ) * ( M2M3 as i64 ) ;
121
- x += ( c2 * i2) . rem_euclid ( M2 as _ ) * ( M1M3 as i64 ) ;
122
- x += ( c3 * i3) . rem_euclid ( M3 as _ ) * ( M1M2 as i64 ) ;
119
+ let mut x = [ ( c1, i1, M1 , M2M3 ) , ( c2, i2, M2 , M1M3 ) , ( c3, i3, M3 , M1M2 ) ]
120
+ . iter ( )
121
+ . map ( |& ( c, i, m1, m2) | c. wrapping_mul ( i) . rem_euclid ( m1 as _ ) . wrapping_mul ( m2 as _ ) )
122
+ . fold ( 0 , i64:: wrapping_add) ;
123
+
123
124
// B = 2^63, -B <= x, r(real value) < B
124
125
// (x, x - M, x - 2M, or x - 3M) = r (mod 2B)
125
126
// r = c1[i] (mod MOD1)
@@ -141,7 +142,7 @@ pub fn convolution_i64(a: &[i64], b: &[i64]) -> Vec<i64> {
141
142
if diff < 0 {
142
143
diff += M1 as i64 ;
143
144
}
144
- x -= OFFSET [ diff. rem_euclid ( 5 ) as usize ] as i64 ;
145
+ x = x . wrapping_sub ( OFFSET [ diff. rem_euclid ( 5 ) as usize ] as _ ) ;
145
146
x
146
147
} )
147
148
. collect ( )
0 commit comments