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;
}



                               

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