HDOJ4196 remoteland

题外话:比赛的时候做这个题TLE好多次,想着求出n!中每个素数的幂,如果幂为奇数的话,就减少一次,然后将他们乘起来。但是使用整数幂乘法太耗时了。


思路:先计算出小于等于n的所有合数的乘积ans。如果小于n的素数的次数是偶数,则ans乘以这个数。




Remoteland

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


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



#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>

typedef long long LL;

using namespace std;
const LL MOD = 1000000007;

LL ans = 1;
vector<LL> G;
bool isprime[10000005];
LL composite[10000005];//n以内合数乘积
void getprime(int n)
{
    memset(isprime,true,sizeof(isprime));
    isprime[1]=false;
    int tot=0;
    composite[1] = composite[2] = 1;
    for(int i=2;i<=n;i++){
        if(isprime[i]){
            tot++;
            G.push_back(i);
            composite[i] = composite[i-1];
        }
        else{
            composite[i] = composite[i-1] *i %MOD;
        }
        for(int j=1;((j<=tot)&&(i*G[j-1]<=n));j++){
            isprime[i*G[j-1]] = false;
            if(i*G[j-1] == 0) break;
        }
    }
}


int main()
{
    getprime(10000000);
    LL n;
    while(~scanf("%I64d", &n)){
        if(!n) break;
        ans = composite[n];
        for(int i = 0; i < G.size() && G[i] <=(n>>1); i++){
            LL cnt = n;
            LL v = G[i];
            LL e = 0;
            while(cnt){
                e += cnt/G[i];
                cnt /= G[i];
            }
            if(e%2 == 0) ans = ans*v %MOD;
        }
        printf("%I64d\n", ans);
    }
    return 0;
}











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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值