hdu 4196 Remoteland 基本算术定理

Remoteland

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)
Total Submission(s): 846    Accepted Submission(s): 305


Problem Description
In the Republic of Remoteland, the people celebrate their independence day every year. However, as it was a long long time ago, nobody can remember when it was exactly. The only thing people can remember is that today, the number of days elapsed since their independence (D) is a perfect square, and moreover it is the largest possible such number one can form as a product of distinct numbers less than or equal to n.
As the years in Remoteland have 1,000,000,007 days, their citizens just need D modulo 1,000,000,007. Note that they are interested in the largest D, not in the largest D modulo 1,000,000,007.
 

Input
Every test case is described by a single line with an integer n, (1<=n<=10,000, 000). The input ends with a line containing 0.
 

Output
For each test case, output the number of days ago the Republic became independent, modulo 1,000,000,007, one per line.
 

Sample Input
  
  
4 9348095 6297540 0
 

Sample Output
  
  
4 177582252 644064736
 

Source
 

Recommend
lcy

题意:要求用 不小于n的数表示出最大的完全平方数。

分析:
n能表示出的最大数就是n!。根据基本算术定理,任何一个大于1的自然数N,都可以唯一分解成有限个质数的乘积 N=(P_1^a1)*(P_2^a2)......(P_n^an) , 这里P_1<P_2<...<P_n是质数,其诸方幂ai 是正整数。若N为完全平方数,则标准式的所有系数都指数为偶数。这样就可以判断如果n!的标准式指数是否为偶数,若为偶数无需处理,若为奇数除以底数即可。但是用快速幂做出题目后,超时。只好另找思路,题目中要求n!这给计算提供了便利,从1到n,依次判断是不是质数,如果为合数直接乘积。容易知道,最后的乘积为 (P_1^(a1-1))*(P_2^(a2-1))......(P_n^(an-1))。然后判断n!的质因数为几次,若为偶次还需乘一次,若为偶次不须处理。

#include <iostream>
#include <cstdio>
using namespace std;
int const maxSize=10000000;
long long ans[10000005];
int isPrime[10000005];
int primes[maxSize],l;
void init()
{
    ans[0] = ans[1] = 1;
    l = 0;
    for (int i=2; i<=maxSize; i++)
    {
        ans[i] = ans[i-1];
        if (!isPrime[i])
        {
            primes[l++] = i;
            if (i < 3163)
                for (int j=i*i; j<=maxSize; j+=i)
                    isPrime[j] = true;
        }
        else
            ans[i] = (ans[i] * i) % 1000000007;
    }
}
int main()
{
    init();
    int n;
    while(~scanf("%d", &n)&& n)
    {
        long long num = ans[n];
        for (int i=0; i<l && primes[i] <= n/2; ++i)
        {
            int cnt = 0;
            int tn = n;
            while(tn >= primes[i])
            {
                tn /= primes[i];
                cnt += tn;
            }
            if (cnt % 2 == 0)
                num = (num * primes[i]) % 1000000007;
        }
        printf("%lld\n", num);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值