解析
被蓝题虐了。(悲
确实不太难,就是没往那边想。
考虑如果某个值的下标分别位 i1,i2,...,ini_1,i_2,...,i_ni1,i2,...,in 那么如何计算贡献。
每一个下标和前面统计时作为被减数,和后面统计时作为减数,所以 iki_kik 的贡献系数就是 (k−1)−(n−k)=2k−n−1(k-1)-(n-k)=2k-n-1(k−1)−(n−k)=2k−n−1。
那么所有下标的统计次数其实就是一个公差为 2 的等差数列:1−n,3−n,...,n−11-n,3-n,...,n-11−n,3−n,...,n−1。
那么现在问题就转化成了,有若干个系数,要求重排使得 ∑i×ai\sum i\times a_i∑i×ai 最大。
显然应该让系数升序排列,这也必然符合了每一个数提供的系数必然从前往后递增的限制。
方案数就是有相同系数时其可以产生一个全排列的阶乘。
现在还有一个问题是系数加在一起是 101110^{11}1011 级别的,无法直接统计。
利用等差数列的性质,奇偶分别差分即可。
代码
//luogu
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
using namespace std;const int N=2e6+100;
const int inf=1e9;
const int mod=1e9+7;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,k;
int o=1e6+10;
int sum[N];
ll jc[N];
ll niv2=(mod+1)/2;
inline ll S(ll x,ll y){ return 1ll*(x+y)%mod*(y-x+1)%mod*niv2%mod;
}
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifn=read();for(int i=1;i<=n;i++){int x=read();sum[1-x+o]++;sum[x-1+o+2]--;}jc[0]=1;for(int i=1;i<=n;i++) jc[i]=jc[i-1]*i%mod;ll val=0,num=1,cnt=0;for(int i=2;i<=o+o;i++){sum[i]+=sum[i-2];num=num*jc[sum[i]]%mod;val=(val+S(cnt+1,cnt+sum[i])*((i-o+mod)%mod))%mod;cnt+=sum[i];}printf("%lld %lld\n",val,num);return 0;
}
/*
*/