I checked my code and it should have the exact same run time as the official solution: my code iterates i through [0, q=primes.size()], x through [0, N], and j through [1, log(x)]. The official code iterates i through [0, primes.size()], j through [0, N], and pp through log(j) iterations.
This means the two programs should have the exact same runtime, but mine is timing out for some reason.
My code:
#include <iostream>
#include <bits/stdc++.h>
#include <fstream>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <math.h>
#include <numeric>
using namespace std;
using ll=long long;
int N, q=0, sieve[10001];
ll M, f[10001][1230];
vector<int> p={0};
void sieveMethod(){
for (int i=2; i<=N; i++) sieve[i]=0;
for (int x=2; x<=N; x++){
if (sieve[x]==0){
for (int j=2*x; j<=N; j+=x) sieve[j]=x;
q++;
}
}
for (int i=2; i<=N; i++){
if (sieve[i]==0) p.push_back(i);
}
}
int main() {
ifstream cin("exercise.in");
cin>>N>>M;
sieveMethod();
for (int i=0; i<=q; i++) f[0][i]=1;
for (int i=0; i<=N; i++) f[i][0]=1;
for (int i=1; i<=q; i++){
for (int x=1; x<=N; x++){
f[x][i]=f[x][i-1];
int m=(int)(log(x)/log(p[i]));
for (int j=1; j<=m; j++){
int pj=(int)(pow(p[i], j));
ll add=((ll)(pj)*f[x-pj][i-1])%M;
f[x][i]=(f[x][i]+add)%M;
}
}
}
ofstream fout("exercise.out");
fout<<f[N][q];
}
Huh, interesting. I did some more tests and it does seem to have something to do with m and not the pow operation inside the loop, or the fact that it’s a for loop (while m-- is also too slow). I’ve spent more than an hour already trying to figure out what’s going on but I still have no idea. Can someone help please?
Also, the solution in post #1 is wrong; the while loop in post #2 does not always take the same number of iterations as the solution in post #1 due to floating point inaccuracy.