【题目大意】:找一个数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;
}