You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
# define int long long
# define endl "\n"
const int Six = 166666668 ; // 6, 2关于mod的乘法逆元
const int Two = 500000004 ;
const int mod = 1e9 + 7 ; // 尽量这样定义mod ,减少非必要的麻烦
int Mod ( int a , int b ) {
return ( a % mod ) * ( b % mod ) % mod ;
}
// 递推函数可以用通项式直接求解
// 通项式: a[kn]=(k*n)^2+k*n
int F ( int k , int n ) {
return ( Mod ( k , k ) * Mod ( Mod ( n , n + 1 ) , Mod ( n + n + 1 , Six ) ) % mod + Mod ( Mod ( 1 + n , n ) , Mod ( k , Two ) ) ) % mod ;
}
vector < int > p ; // 将m拆分成的质数因子序列p
signed main ( ) {
# ifndef ONLINE_JUDGE
freopen ( " SpareTire.in " , " r " , stdin ) ;
# endif
int n , m ;
while ( cin > > n > > m ) {
int sum = F ( 1 , n ) , ans = 0 ; // 计算总和sum
// 质因子分解
int t = m ; // 复制出来
for ( int i = 2 ; i * i < = t ; i + + ) {
if ( t % i = = 0 ) {
p . push_back ( i ) ;
while ( t % i = = 0 ) t = t / i ;
}
}
if ( t > 1 ) p . push_back ( t ) ;
// 开始容斥
// 例如有3个因子, 那么item=1<<3=8(1000二进制)
// 然后i从1开始枚举直到7(111二进制) , i中二进制的位置1表式取这个位置的因子
// 例如i=3(11二进制) 表示去前两个因子, i=5( 101) 表示取第1个和第3个的因子
for ( int i = 1 ; i < ( 1 < < p . size ( ) ) ; i + + ) {
int cnt = 0 , s = 1 ;
for ( int j = 0 ; j < p . size ( ) ; j + + )
if ( ( i > > j ) & 1 ) {
cnt + + ;
s * = p [ j ] ;
}
if ( cnt & 1 )
ans = ( ans + F ( s , n / s ) ) % mod ; // 根据容斥,取奇数个因子时,应加上
else
ans = ( ( ans - F ( s , n / s ) ) % mod + mod ) % mod ; // 偶数的减,减法需要防负数
}
// 补集,标准取模动作
cout < < ( ( sum - ans ) % mod + mod ) % mod < < endl ;
}
}