fi,j
表示前
i
个质数,能组成小于等于
转移简单,但是记忆化会爆内存
倒过来考虑,
fi,j
表示用了后
i
个质数的方案数,那么当
// BEGIN CUT HERE
// END CUT HERE
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <assert.h>
#include <cstring>
#include <tr1/unordered_map>
#define pb push_back
#define fi first
#define se second
using namespace std;
using namespace tr1;
typedef long long ll;
typedef pair<int,ll> par;
const int N=1000010;
int p[N];
inline void Pre(int n){
for(int i=2;i<=n;i++){
if(!p[i]) p[++*p]=i;
for(int j=1;j<=*p && 1LL*p[j]*i<=n;j++){
p[p[j]*i]=1;
if(i%p[j]==0) break;
}
}
}
int ttt;
ll dp(int n,ll m){
if(n>*p || p[n]>m) return 1;
if(1LL*p[n]*p[n]>m) return upper_bound(p+1,p+1+(*p),m)-p-n+1;
ll ret=dp(n+1,m);
for(ll i=p[n];i<=m;i*=1LL*p[n]*p[n])
ret+=dp(n+1,m/i);
return ret;
}
class HolyNumbers{
public:
long long count(long long upTo, int maximalPrime) {
memset(p,0,sizeof(p)); Pre(maximalPrime);
return dp(1,upTo);
}
// BEGIN CUT HERE
public:
void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); }
private:
template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
void verify_case(int Case, const long long &Expected, const long long &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
void test_case_0() { long long Arg0 = 10LL; int Arg1 = 100; long long Arg2 = 8LL; verify_case(0, Arg2, count(Arg0, Arg1)); }
void test_case_1() { long long Arg0 = 10LL; int Arg1 = 3; long long Arg2 = 5LL; verify_case(1, Arg2, count(Arg0, Arg1)); }
void test_case_2() { long long Arg0 = 123LL; int Arg1 = 12; long long Arg2 = 32LL; verify_case(2, Arg2, count(Arg0, Arg1)); }
void test_case_3() { long long Arg0 = 123LL; int Arg1 = 456; long long Arg2 = 88LL; verify_case(3, Arg2, count(Arg0, Arg1)); }
void test_case_4() { long long Arg0 = 123456789LL; int Arg1 = 12345; long long Arg2 = 25994500LL; verify_case(4, Arg2, count(Arg0, Arg1)); }
// END CUT HERE
};
// BEGIN CUT HERE
int main()
{
HolyNumbers ___test;
___test.run_test(-1);
system("pause");
}
// END CUT HERE