TopCoder SRM 569 Div2 1000 MegaFactorialDiv2

这次的1000好简单啊w(゚Д゚)w
然而我还是FST了。。因为中间忘记模了。。。

好像就是个大暴力啊
可以直接根据题目给出的递推式把 n ! k 个各个质因子个数递推出来(不过空间开不下要用滚动数组)
求因子个数有个公式相信大家小学就知道了
x = p 1 a 1 p 2 a 2 p m a m ,其中 p 1 , p 2 , , p m 为质数
x 的因子个数为 a 1 a 2 a m
就相当于对每个质因子 p i 可以选 [ 0 , a i ] 次,共有 a i + 1 种选法,根据乘法原理乘起来就行了。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1001;
const int P=1e9+9;
int L,b[N],p[N],s[N];
ll f[2][N][N];

class MegaFactorialDiv2 {
public:
    int countDivisors( int n, int K );
};

void init(int n){
    memset(f,0,sizeof f);
    for(int i=2;i<=n;i++){
        if (!b[i]) p[++L]=i;
        for(int j=1;j<=L&&i*p[j]<=n;j++){
            b[i*p[j]]=1;
            if (i%p[j]==0) break;
        }
    }
    //for(int i=1;i<=25;i++) cout<<p[i]<<' ';
}

int MegaFactorialDiv2::countDivisors(int n, int K) {
    init(N-1);
    int cur=0;
    for(int o=1;o<=n;o++){
        cur^=1;
        memset(f[cur],0,sizeof f[cur]);
        int x=o;
        for(int i=1;i<=L;i++)
         while(x%p[i]==0) x/=p[i],f[cur][0][i]++;
        for(int i=1;i<=K;i++)
         for(int j=1;j<=L;j++)
          f[cur][i][j]=(f[cur^1][i][j]+f[cur][i-1][j])%P;
    }
    ll ans=1;
    for(int i=1;i<=L;i++)
     ans=ans*(f[cur][K][i]+1)%P;
    return (int) ans%P;
}

猜你喜欢

转载自blog.csdn.net/ymzqwq/article/details/81636004