• HDU 5297 Y sequence 容斥 迭代


    Y sequence

    题目连接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5297

    Description

    Yellowstar likes integers so much that he listed all positive integers in ascending order,but he hates those numbers which can be written as a^b (a, b are positive integers,2<=b<=r),so he removed them all.Yellowstar calls the sequence that formed by the rest integers“Y sequence”.When r=3,The first few items of it are:
    2,3,5,6,7,10......
    Given positive integers n and r,you should output Y(n)(the n-th number of Y sequence.It is obvious that Y(1)=2 whatever r is).

    Input

    The first line of the input contains a single number T:the number of test cases.
    Then T cases follow, each contains two positive integer n and r described above.
    n<=2*10^18,2<=r<=62,T<=30000.

    Output

    For each case,output Y(n).

    Sample Input

    2
    10 2
    10 3

    Sample Output

    13
    14

    Hint

    题意

    有一个序列,一开始是1,2,3,4,5,....,inf 这样的。

    然后这个序列把a^b(1<b<=r)都删除掉了。

    现在给你n,r。

    问你这个序列的第n项是什么。

    题解:

    假设我们知道了cal(x)表示包括x在内的x之前这个序列有多少个数。

    那么显然我们就可以直接二分乱搞就好了。

    然后cal怎么做呢?

    x^(1/b)就表示x范围内有多少个a^b次方的数,然后根据这个容斥一波就好了。

    比如你减去了2次方的,减去了3次方的,但是你多减了6次方的,你得加回去。

    然后你就做完了。

    还有一个问题就是二分会TLE,所以你就只能换成迭代做了……

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int prime[100],cnt;
    long long n;int m;
    vector<int>v;
    void init()
    {
        int tot=2;
        while(1)
        {
            if(tot>100)break;
            int flag=0;
            for(int i=2;i<tot;i++)
                if(tot%i==0)flag=1;
            if(flag==0)prime[cnt++]=-tot;
            tot++;
        }
    }
    void init2()
    {
        v.clear();
        for(int i=0;-prime[i]<=m;i++)
        {
            int tot = v.size();
            for(int j=0;j<tot;j++)
                if(abs(v[j]*prime[i])<=63)
                    v.push_back(v[j]*prime[i]);
            v.push_back(prime[i]);
        }
    }
    long long cal(long long x)
    {
        long long ra = 0;
        for(int i=0;i<v.size();i++)
        {
            long long tmp = exp(log(x+0.5)/abs(v[i]))-1;
            if(v[i]<0)ra=ra+tmp;
            else ra=ra-tmp;
        }
        return x-ra-1;
    }
    int main()
    {
        init();
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%lld%d",&n,&m);
            init2();
            long long ans = n,tmp = cal(n);
            while(tmp<n)
            {
                ans=ans+n-tmp;
                tmp=cal(ans);
            }
            printf("%lld
    ",ans);
        }
    }
  • 相关阅读:
    java基础之System类
    java基础之System类
    java基础之Random类
    java基础之Math类
    java基础之Math类
    java基础之Character类概述
    MySQL数据库
    JavaScript面向对象与原型
    PHP
    sass基础用法
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5274794.html
Copyright © 2020-2023  润新知