可能会有点用,另外quickpow常数有点大啊,如果用的都是一样的一定要提前计算。
http://www.51nod.com/Challenge/Problem.html#!#problemId=1225
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7, mod2 = 998244353, inf = 0x3f3f3f3f;
ll quickpow(ll x, ll k)
{
ll res = 1;
while(k){
if(k & 1) res = (res * x) % mod;
k >>= 1, x = (x * x) % mod;
}
return res;
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
ll n;
cin >> n;
ll ans = 0, inv2 = quickpow(2, mod - 2);
for (ll l = 1, r; l <= n; l = r + 1){
r = n / (n / l);
ans -= (n / l) % mod * ((l + r) % mod) % mod * ((r - l + 1) % mod) % mod * inv2 % mod;
}
ans = n % mod * (n % mod) + ans;
ans %= mod; ans += mod; ans %= mod;
cout << ans << endl;
return 0;
}
应用
https://www.luogu.org/problemnew/show/P2260
注意一下n和m有没有提出来啊没提出来就不用乘了啊sb啊因为已经计算过了啊这种要取模的题真麻烦很难找错。
另外注意一下模数是否为质数,不是请使用欧拉定理,再不互质请使用扩展欧拉定理,可能会有些毒瘤出题人。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 19940417;
ll quickpow(ll x, ll k)
{
ll res = 1;
while(k){
if(k & 1) res = (res * x) % mod;
k >>= 1, x = (x * x) % mod;
}
return res;
}
ll euler(ll x)
{
ll res = x;
for(ll i = 2; i * i <= x; ++i){
if(x % i == 0){
res = res / i * (i - 1);
while(x % i == 0) x /= i;
}
}
if(x > 1) res = res / x * (x - 1);
return res;
}
ll inv6;
ll sum1(ll l, ll r)
{
return (l + r) * (r - l + 1) / 2 % mod;
}
ll sum2(ll x)
{
return x * (x + 1) % mod * (2 * x + 1) % mod * inv6 % mod;
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
inv6 = quickpow(6, euler(mod) - 1);
ll n, m;
cin >> n >> m;
if (n > m) swap(n, m);
ll sn = n * n % mod, sm = m * m % mod, sum = 0;
//\sum_{i = 1}^{n} (n / i) * i
for (ll l = 1, r; l <= n; l = r + 1){
r = n / (n / l);
sn -= (n / l) * sum1(l, r) % mod;
sn = (sn % mod + mod) % mod;
}
//\sum_{i = 1}^{m} (m / i) * i
for (ll l = 1, r; l <= m; l = r + 1){
r = m / (m / l);
sm -= (m / l) * sum1(l, r) % mod;
sm = (sm % mod + mod) % mod;
}
//\sum_{i = 1}^{n} (n / i) * (m / i) * i^2 - ((m * (n / i) + n * (m / i)) * i)
for (ll l = 1, r; l <= n; l = r + 1){
r = min(n / (n / l), m / (m / l));
sum += (m / l) * (n / l) % mod * (sum2(r) - sum2(l - 1)) % mod;
sum -= (m * (n / l) % mod + n * (m / l) % mod) * sum1(l, r) % mod;
sum = (sum % mod + mod) % mod;
}
ll ans = sn * sm % mod - (n * n % mod * m % mod + sum);
ans = (ans % mod + mod) % mod;
cout << ans << endl;
return 0;
}