hdu 1061
纯快速幂
hdu 3033
这题的大意是:一种动物身上有n种不同的皮肤,每种皮肤有透明很不透明两种状态,经过一天的日晒,透明的可以变成不透明,不透明的可以变成透明,但是需要注意的是,如果皮肤的外层是透明的话,阳光可以照射到内层,如果是不透明的话,则不可以。
然后刚出生的动物身上的皮肤都是不透明的,问多少天后,全部的皮肤都变过透明的。。
递推公式:res=(2^(n-1)+1)mod(n)
hdu 4196
题目:用不大于n内的所有数去组成一个尽可能大的完全平方数。
完全平方数,显然是所有的素因子的个数都是偶数,便取N!的所有素因子的个数,便 有了初步想法,算出N!的什么素因子个数,奇数的就舍去一个,偶数的全要,然后再全部乘起来,可是因为规模很大,即使快速幂乘也是会超时。
于是考虑把N!除掉那些奇数个因子的乘积,便是求a=c/b,由于是取模的,直接除必然不行。
考虑c%mod=(a%mod)*(b%mod);令A=a%mod; B=b%mod;C=c%mod;
则A=a%mod=(a*1)%mod=a%mod*1%mod=(a%mod)*(b^(mod-1))%mod --------因为(b^(mod-1))%mod=1,费马小定理。
=(a*b)%mod*(b^(mod-2))%mod=(c%mod)*(b%mod)^(mod-2)%mod=C*B^(mod-2)
利用这个,就可以求出c/b的结果。
(PS:product 翻译为 乘积!)代码:
#include <stdio.h>
#include <math.h>
#define N 10000001
#define M 3000000
#define MOD 1000000007
__int64 fac[N];
int pri[N];
int cnt;
void p()
{
fac[0] = 1;
int i,j;
for(i = 1; i < N; ++i)
fac[i] = i * fac[i-1] % MOD;
int n = sqrt(N*1.0);
for(i = 2; i <= n; ++i)
if(!pri[i])
for(j = i * i; j < N; j += i)
pri[j] = 1;
for(i = 2; i < N; ++i)
if(!pri[i])
pri[cnt++] = i;
}
__int64 fastPow(__int64 p,int d)
{
__int64 ans = 1;
while(d)
{
if(d&1)
ans = (ans * p) % MOD;
d >>= 1;
p = (p * p) % MOD;
}
return ans;
}
int getSum(int n,int p) //这是求n!中质因子p的幂的次数
{
int sum = 0;
while(n)
{
sum += n/p;
n /= p;
}
return sum;
}
int main()
{
p();
__int64 b;
int n,i;
while(scanf("%d",&n) == 1 && n)
{
b = 1;
for(i = 0; i < cnt && pri[i] <= n; ++i)
{
if((getSum(n,pri[i])) & 1)
b = b * pri[i] % MOD;
}
printf("%I64d\n",fac[n]*fastPow(b,MOD-2)%MOD);
}
return 0;
}