2015 Multi-University Training Contest HDU5297

来源:互联网 发布:软件测试人员保密协议 编辑:程序博客网 时间:2024/05/18 02:25

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=5297

题意:给定正整数n和r,定义Y数列为从正整数序列中删除所有能表示成a^b(2 ≤ b ≤ r)的数后的数列,求Y数列的第n个数是多少。例如n = 10, r = 3,则Y数列为2 3 5 6 7 10 11 12 13 14,第10个数是14。


一个相当水的容斥原理的题目。然而比赛并没有几个人过。。

本题其实就是求一个N,使得N-f(N)=n。其中f(n)为所有能表示成a^b(2 ≤ b ≤ r)的数的个数。则可以从n开始算(N肯定不小于n),然后根据容斥原理算出f(n),一个DFS解决问题。注意1的问题,先把1剔掉,最后再加回来。下面直接上代码


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define eps 1e-7
ll n,m;
ll prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67};
ll dfs(ll n,ll pre,int cur)
{
    ll ans=0;
    for(int i=cur;prime[i]<=m;i++)
    {
        if(pow(2,prime[i]*pre)>n)
            break;
        ans+=(ll)(pow(n,1.0/(pre*prime[i]))+eps)-1;
        ans-=dfs(n,pre*prime[i],i+1);
    }
    return ans;
}
ll get(ll n)
{
    ll ans=dfs(n,1,0);
    return n-ans-1;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d%I64d",&n,&m);
        ll ans=n;
        while(1)
        {
            ll tmp=get(ans);
            if(tmp==n)
                break;
            ans+=n-tmp;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


0 0
原创粉丝点击