A Partial Order Relation UVALive - 8270

这张图就已经能提供很多样例了。

30 : 12

12:  7

24: 10

……

其实我就是一直在纠结确定一个质数之后,选择其他的质数(肯定和它们的个数相关)有多少种方案。

但其实并没我之前甚至用组合数那么复杂。。。

拿24 = 2 * 2 * 2 * 3;

对于 2 来说,它出现三次,那么你就有三种选择方案   2  、  4  、 8。

然后 3 只出现了一次, 你可选可不选【不选其实就选的是1】 那么就是 两种方案。 乘法原理, 枚举2时有 6 个方案。


然后还有 对于3 来说  同理可得你有一种方案 就只能选择 3.

然后 2 出现了三次, 有四种方案,  不选(1)、  2、  4、  8。   共四种方案。


答案就是 10;


综上, 做法就是枚举每个质数, 然后根据它自己的次数和其他质数出现的次数求出对应答案, 答案加和。

这样做就根据了每个数出现的次数来限定乘除来的数一定小于n, 且是n的因子。

上代码。

#include<bits/stdc++.h>
#define ms(x) memset(x, 0, sizeof(x))
#define ll long long
using namespace std;
const int N=1000003;
vector<int>vec;
bool ispri[N];
int pri[100000], o;
void getpri() {
    ms(ispri);
    for(int i=2; i<=N-2; i++) {
        if(!ispri[i]) pri[o++] = i;
        for(int j=i+i; j<=N-2; j+=i) {
            ispri[j] = 1;
        }
    }
}
int fatcnt;
ll factor[100][2];
int allsum = 0;
ll getfactors(ll x) {
    fatcnt = 0;
    ll tmp = x;
    for(int i=0; pri[i]<=tmp/pri[i]; i++) {
        factor[fatcnt][1] = 0;
        if(tmp%pri[i]==0) {
            factor[fatcnt][0] = pri[i];
            while(tmp%pri[i]==0) {
                factor[fatcnt][1]++;
                tmp/=pri[i];
            }
            fatcnt++;
        }
    }
    if(tmp!=1) {
        factor[fatcnt][0] = tmp;
        factor[fatcnt++][1] = 1;
    }
    return fatcnt;
}
int main() {
    o = 0;
    allsum = 0;
    int T;
    getpri();
    scanf("%d",&T);
    while(T--) {
        ll n;
        scanf("%lld", &n);
        ll sum = getfactors(n);   // allsum
        ll ans = 0;
        for(int i=0;i<sum;i++){
            ll tmp = factor[i][1];
            for(int j=0;j<sum;j++){
                if(i==j) continue;
                else{
                    tmp *= (factor[j][1] + 1);
                }
            }
            ans += tmp;
        }
        printf("%lld\n",ans);
    }
    return 0;
}




猜你喜欢

转载自blog.csdn.net/khn64/article/details/80564195