题目描述的意思就不说了,自己考虑的时候就是在所有的排列中,碰到大于前面最大的出现数字的时候就乘以一个二分之一,然后求和。
打表后就会发现,答案分子为1*3*5*……*(2*n-1);分母为2*4*6*……*(2*n),这样就很简单了。
直接保存每一个因子出现的次数,然后。。。就可以了。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#define M 1000000
#define maxn 1011
using namespace std;
struct node{
int top,s[1000];
void init()
{
for (int i=0; i<=top; i++) s[i]=0;
top=0,s[0]=1;
}
void mul(int x)
{
for (int i=0; i<=top; i++) s[i]*=x;
for (int i=0; i<top; i++)
if (s[i]>=M) s[i+1]+=s[i]/M,s[i]%=M;
while (s[top]>=M) s[top+1]=s[top]/M,s[top]%=M,top++;
}
void output()
{
printf("%d",s[top]);
for (int i=top-1; i>=0; i--) printf("%06d",s[i]);
}
}ans1,ans2;
int a[maxn],pri[maxn],Pnum=0;
bool b[maxn];
void getprim()
{
for (int i=2; i<maxn; i++)
{
if (b[i]) continue;
pri[++Pnum]=i;
for (int j=i+i; j<maxn; j+=i) b[j]=true;
}
}
void add(int x,int v)
{
for (int i=1; pri[i]<=x; i++)
{
while (x%pri[i]==0) x/=pri[i],a[i]+=v;
}
}
int main()
{
int T,n;
getprim();
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
memset(a,0,sizeof a);
for (int i=1; i<=2*n; i+=2) add(i,1);
for (int i=2; i<=2*n; i+=2) add(i,-1);
ans1.init(),ans2.init();
for (int i=1; i<=Pnum; i++)
{
while (a[i]>0) ans1.mul(pri[i]),a[i]--;
while (a[i]<0) ans2.mul(pri[i]),a[i]++;
}
ans1.output();
printf("/");
ans2.output();
printf("
");
}
return 0;
}