【題目大意】:找一個數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;
}