题意:固定起点是0,给出一个序列表示n个点,所有点都在一条直线上,其中每个元素代表了从起点到这个点所走的距离。已知路过某个点不算到达这个点,则从起点出发,到达所有点的方案有许多种。求所有方案走的总路程/方案数,输出分子、分母,要求不含约数
容易得到方案数为n!,n<=1e5,显然需要优化式子,如何求所有方案走的路程和?
求总的路程和,考虑边的出现次数:(0,ak)(n-1)! ,多少条路径包含边(u,v) 从(n-1)个位置总选出一个剩下n-2条边可以任意排(n-2)! 则化解为ans= 总的边权和/n
直接枚举求边权和显然TLE 利用DP令dp[i]为i之前的总边权和 dp[i+1]=(p[i]-p[i-1]])*i+dp[i] 即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+20;
ll n,p[N];
ll gcd(ll a,ll b)
{
if(a%b==0)
return b;
else
return gcd(b,a%b);
}
ll d[N];//d[i] i~j (j<i)的距离累加和
int main()
{
while(cin>>n)
{
ll e=0,s=n;
p[0]=0;
for(int i=1;i<=n;i++)
scanf("%I64d",&p[i]);
sort(p,p+1+n);
d[0]=0;
ll sum=0;
for(int i=1;i<=n;i++)
{
ll t=p[i]-p[i-1];
d[i]=d[i-1]+i*t;//0~i-1,i段,先经过i-1->i
e+=d[i];
sum+=p[i];
}
e*=2;//双向边
e-=sum;//u->0不存在
ll d=gcd(s,e);
cout<<e/d<<' '<<s/d<<endl;
}
return 0;
}