正着求sum会WA两个点
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int N = 1000007;
typedef long long ll;
ll mod = 1e9 + 7;
ll n, m, cnt;
int primes[N];
bool vis[N];
void get_primes(ll n)
{
vis[0] = vis[1] = 1;
for(int i = 2; i <= n; ++ i){
if(vis[i] == 0){
primes[++ cnt] = i;
}
for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j){
vis[i * primes[j]] = true;
if(i % primes[j] == 0)break;
}
}
}
ll qpow(ll a, ll b)
{
ll res = 1;
while(b){
if(b & 1)res = (res * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return res;
}
int main(){
scanf("%lld", &n);
get_primes(n);
ll ans = 1;
for(int i = 1; i <= cnt; ++ i){
int p = primes[i];
ll sum = 0;
for(int j = 1; qpow(p, j) <= n; ++ j){
sum = sum + n / qpow(p, j);
}
ans = ans * (2 * sum + 1) % mod;
}
printf("%lld\n", ans % mod);
return 0;
}
倒着求sum就AC了
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int N = 1000007;
typedef long long ll;
ll mod = 1e9 + 7;
ll n, m, cnt;
int primes[N];
bool vis[N];
void get_primes(ll n)
{
vis[0] = vis[1] = 1;
for(int i = 2; i <= n; ++ i){
if(vis[i] == 0){
primes[++ cnt] = i;
}
for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j){
vis[i * primes[j]] = true;
if(i % primes[j] == 0)break;
}
}
}
int main(){
scanf("%lld", &n);
get_primes(n);
ll res = 1;
for(int i = 1; i <= cnt; ++ i){
int p = primes[i];
int sum = 0;
for(int j = n; j; j /= p)
sum += j / p;
res = (res * (2 * sum + 1)) % mod;
}
cout << res % mod << endl;
return 0;
}
for(int j = 1; qpow(p, j) <= n; ++ j)
sum = sum + n / qpow(p, j);
for(int j = n; j; j /= p)
sum += j / p;
这两种有什么区别嘛