hdoj 4196 Remoteland(筛素数+奇偶判断)

【题目大意】:找一个数D,是一个平方数,且他是由<=n中的若干个数构成。D要尽可能大,求D是多少。答案mod  1000000007


【解题思路】.:这道题兜了一个大圈,其实写写就会发现其实是找一个最大的平方数使得这个数是n!的除数。。。

        然后,这道题就变得简单了。。。。。。。。

         筛一次素数,然后求n!每一个素数出现多少次,出现偶数次的必然是D的因子,出现奇数次的,由于是该素数必定小于等于n只要除去该素数之后其他也必定属于D

         所以,筛素数+快速幂...然后无情的TLE TLE TLE TLE,试过了输入挂,试过了筛两次素数,其实自己也心知肚明问题出在快速幂那里。。。

想不出的时候,就要YY  -_-!!!!!

          然后,我发现,其实在筛素数的时候可以顺便把合数累乘起来,保存在一个数组中,以后每发现出现偶数次的质因子就补乘上该质数即可。在筛素数O(n)的时候顺便预处理了,避免了快速幂....也许是我能想到的优化不多,瞬间发现这个优化确实很有效。

  

【代码】:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>
                   
using namespace std;
                   
#define eps 1e-8
#define pi acos(-1.0)
#define inf 1<<30
#define linf 1LL<<60
#define pb push_back
#define lc(x) (x << 1)
#define rc(x) (x << 1 | 1)
#define lowbit(x) (x & (-x))
#define ll long long
#define mod 1000000007

bool is[10000100];
int prm[2001000];
int anss[10000100];
int cnt,num,n;

int get_prime(int n)
{
	ll i,j,k=0;
	anss[0]=anss[1]=1;
    for (i=2; i<=n; i++) {
        anss[i]=anss[i-1];
	   if (!is[i])
	   {
	      prm[k++]=i;
	      for (j=i*i; j<=n; j+=i)
	          is[j]=1; 
	   }
       else anss[i]=anss[i]*i%mod;
    }
	return k;                   
}

int main() {
    num=get_prime(10000010);
     while (~scanf("%d",&n)){
        if (n==0) break;
        ll ans=anss[n];
        for (int i=0; i<num && prm[i]<=n; i++){
            int tmp=n;
            int cnt=0;
            while (tmp){
                cnt+=tmp/prm[i];
                tmp/=prm[i];
            }
            if (cnt%2==0) ans=ans*prm[i]%mod;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}



                               

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章