码迷,mamicode.com
首页 > 其他好文 > 详细

容斥定理 hdu2204 Eddy's爱好

时间:2015-08-18 22:59:01      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:

传送门:点击打开链接

很明显会有大量重复的被计算,所以很容易就想到容斥定理。

我们设dp[i]表示能表示成M^i(i>1)且i是这个数字能表示出来的最大的情况时的总类数

比如,27拆成M^K时的K最大能表示成3,所以27这个数字分在dp[3]这一类

1我们暂时不考虑,不把它放在任何一类


因为K>1,所以K至少是2,最大是2^K=N的时候,所以K最大等于log2(N),所以K非常的小

首先,求出K最大大概的位置

然后开始求dp[i]。求法如下:

首先,1~N中有哪些是能拆分成M^i的,利用pow函数可以算出来,暂时记为dp[i]

按照dp[i]的要求,还必须要排除K目前不是表示最大的情况,相当于容斥了,如下

dp[i]=dp[i]-dp[2*i]-dp[3*i]-dp[4*i]-.......

这样处理完后,dp[i]就是能表示成M^i(i>1)且i是这个数字能表示出来的最大的情况时的总类数了

最后的答案就是dp[2]+dp[3]+....+dp[K的最大值],再加上我们之前没考虑的1就可以了

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cctype>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int MX = 1e3 + 5;
const double exps = 1e-8;

LL dp[MX];

int main() {
    LL n;//FIN;
    while(~scanf("%I64d", &n)) {
        memset(dp, 0, sizeof(dp));
        int p = ceil(log2(1.0 * n)) + 1;

        LL ans = 1;
        for(int i = p; i >= 2; i--) {
            dp[i] = pow(1.0 * n, 1.0 / i) - 1 + exps;
            for(int j = 2 * i; j <= p; j += i) {
                dp[i] -= dp[j];
            }
            ans += dp[i];
        }
        printf("%I64d\n", ans);
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

容斥定理 hdu2204 Eddy's爱好

标签:

原文地址:http://blog.csdn.net/qwb492859377/article/details/47759471

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!