#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
typedef long long LL;
const int N=1001000;
const int MOD=20000003;
LL dp[N];
void extend_Euclid(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return;
}
extend_Euclid(b,a%b,x,y);
LL tmp=x;
x=y;
y=tmp-(a/b)*y;
}
void Solve()
{
dp[1] = 1;
dp[2] = 1;
dp[3] = 2;
LL ans=2;
int a=2,b=1,bit=3,h=2;
bool is_left = 1;
int x,y;
for(int i=4; i<=1000000; i++)
{
a++;
if(is_left)
{
b++;
extend_Euclid(b,MOD,x,y);
x=(x+MOD)%MOD;
ans=ans*a%MOD*x%MOD;
if(b==bit) is_left=0;
}
else
{
extend_Euclid(a-b,MOD,x,y);
x=(x+MOD)%MOD;
ans=ans*a%MOD*x%MOD;
if(a==b+b) is_left=1,h*=2,bit+=h;
}
dp[i]=dp[b]*dp[a-b]%MOD*ans%MOD;
}
}
int main()
{
int n;
Solve();
while(~scanf("%d",&n))
{
printf("%lld\n",dp[n]);
}
return 0;
}
另一种方法:
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
using namespace std;
typedef long long LL;
const int N=1000005;
const int MOD=20000003;
struct node
{
int root;
int lc,rc;
};
LL pans[N];
int cnt[N];
int p[N];
bool prime[N];
int k;
LL quick_mod(LL a,LL b)
{
LL ans=1;
a%=MOD;
while(b)
{
if(b&1)
{
ans=ans*a%MOD;
b--;
}
b>>=1;
a=a*a%MOD;
}
return ans;
}
void isprime()
{
int i,j;
k=0;
memset(prime,true,sizeof(prime));
for(i=2;i<N;i++)
{
if(prime[i])
{
p[k++]=i;
for(j=i+i;j<N;j+=i)
{
prime[j]=false;
}
}
}
}
LL getMany(LL n,LL p)
{
LL t=0;
LL ans=p;
while(ans<=n)
{
t+=n/ans;
ans*=p;
}
return t;
}
LL getC(LL n,LL m)
{
LL temp,ans;
ans=1;
for(int i=0;p[i]<=n;i++)
{
temp=getMany(n,p[i])-getMany(n-m,p[i])-getMany(m,p[i]);
ans=(ans*quick_mod(p[i],temp))%MOD;
}
return ans;
}
LL dfs(LL n)
{
if(pans[n]!=-1)
return pans[n];
pans[n]=((((getC(n-1,cnt[n])*dfs(cnt[n]))%MOD)*dfs(n-1-cnt[n]))%MOD);
return pans[n];
}
int main()
{
int n;
pans[0]=0;
pans[1]=1;
pans[2]=1;
isprime();
node now;
now.root=3;
now.lc=1;
now.rc=1;
int num=0;
for(int i=3;i<N;i++)
{
pans[i]=-1;
if(num<now.lc)
num ++;
cnt[i]=num;
if(i==now.root)
{
now.lc=now.rc=now.root;
now.root=2*now.root+1;
}
}
while(scanf("%d",&n)!=EOF)
{
dfs(n);
printf("%lld\n",pans[n]);
}
return 0;
}