首先比较容易得到的是对于n个目的地一共有n!种方案。也就是分母是n!,然后我们考虑一个问题,在每一种方案中一共有多少条路?这里一条路指的是从a点到达b点。
这个地方卡我了好久,刚才才想明白,其实一共有n条路。理由:so简单,因为一共有n个终点,每个终点都是一条路。
然后我们算一下,在这n!种方案中一共出现了多少条路?很明显,是n!*n条路。这时候重点来了,对于n个目的地来说,一共有多少条不同的路,也是好算,就是A(n,2),从n个点中挑出两个点,一个是起点,一个是终点。但是这其中要减去从1~n返回到0的路,因为0是不能作为终点的。这样我们就得到了一共n*n条路。而且这些路都是等价的,也就是说在这n!种方案中出现的次数是相同的。
这样的话,总的路出现的次数是n*n!,路的种类是n*n,那么每条路出现的次数也就是(n-1)!。
化简一下,分母就变成了n,分子就是所有的路的和。求这个和的时候需要用上一点儿小技巧,但是和前面的推论比起来就so easy了。
计算过程中需要注意会超int。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 500005
typedef long long LL;
LL a[N];
LL fun(LL x,LL y)
{
LL k;
if(x>y)
{
k=x;
x=y;
y=k;
}
k=1;
while(k>0)
{
k=y%x;
y=x;
x=k;
}
return y;
}
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
int main()
{
LL am,az;
int n;
while(scanf("%d",&n)!=EOF)
{
int i;
for(i=1;i<=n;i++)
scanf("%I64d",&a[i]);
qsort(a+1,n,sizeof(a[1]),cmp);
am=n;
LL x,y,z;
x=0;
z=0;
for(i=1;i<=n;i++)
{
x+=(i-1)*a[i];
z+=a[i];
}
y=0;
int k=n-1;
for(i=1;i<=n-1;i++)
{
y+=k*a[i];
k--;
}
az=(x-y)*2;
az+=z;
LL m;
m=fun(am,az);
printf("%I64d %I64d\n",az/m,am/m);
}
return 0;
}