牛客2021寒假训练营J题快速幂+筛质数

来源:牛客网

有n个格子,每个格子里有一个数,1,2,3,4...n

牛牛放出无穷只青蛙。
第一只青蛙的路线是:1->2->4->8->16->....
第二只青蛙的路线是:1->3->9->27->81->....
第三只青蛙的路线是:1->5->25->125....
第四只青蛙的路线是:1->7->49........
。。。。。。
用数学语言描述,第 只青蛙的路线是首项为1,公比为的等比数列,其中代表第个素数。
当青蛙跳到一个格子上,如果这个格子上面有一个数,青蛙就会把这个数吃掉。
牛牛想知道,所有没有被吃掉的数的lcm(最小公倍数 ,Least common multiple)是多少?
由于这个lcm可能非常大,请输出它对取模的值。
输入描述:
一个正整数

输出描述:
如果所有数都被吃掉了,请输出一个字符串"empty"
否则输出所有没有被吃掉的数的lcm,对取模
示例1
输入
复制
7
输出
复制
6
说明
数字 1 可以被所有青蛙吃掉;
数字 2 可以被第 1 只青蛙吃掉;
数字 3 可以被第 2 只青蛙吃掉;
数字 4 可以被第 1 只青蛙吃掉;
数字 5 可以被第 3 只青蛙吃掉;
数字 6 无法被吃掉;
数字 7 可以被第 4 只青蛙吃掉。
所以剩下的数字只有一个 6 ,所有数的 lcm 为 6
示例2
输入
复制
123456789
输出
复制
539747460

先根据唯一分解定理进行分解
每个能被筛去的数就2 ^ k , 3 ^ k , 5 ^ k
那么如果分解的质因数个数>=2个就不会被筛去了
然后n = p1^a1 , p2 ^ a2.....
然后m =p1^b1 , p2 ^ b2....
然后求最小公倍数 p1 ^ max(a1,b1)
其实就是求每个质因数的最高次幂那么如果不是2的话那他的最高次幂
2 *  x ^ k <= n 用log 表述出来
如果是2就是 3 * 2 ^ k  <= n 在表示出来最大值
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 80000005 , mod = 1e9 + 7;
int n;
int p[N] , st[N];
LL ans = 1;
LL ksm(int a , int b)
{
    LL res = 1 , t = b;
    while(t)
    {
        if(t & 1) res = res * a % mod;
        a = (LL) a * a % mod;
        t >>= 1;
    }
    return res;
}
LL cal(int x)
{
    if(x == 2) return ksm(x ,floor(log2(n / 3) ) );
     return ksm(x , floor(log(n / 2) / log (x) )  );
}

void get_prime()
{
    int cnt = 0;
    for(int i= 2 ;i <= n / 2; i ++)
    {
        if(!st[i])
        {
            p[cnt ++] = i;
            ans = ans * cal(i) % mod;
        }
        for(int j = 0 ;j < cnt && i * p[j] <= n / 2 ; j ++) 
        {
            st[i * p[j]] = 1;
            if(i % p[j] == 0) break;
        }
    }
}

int main()
{
    cin >> n;
    get_prime();
    if(ans == 1) cout <<"empty"<<endl;
    else 
    cout << ans;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值