傳送門
- 考慮枚舉各維最大最小座標的差量 Δi,可以寫出式子:Ans=Δ∑(c−2gcd(Δ1...n)−1)i=1∏n(mi−Δi)=d∑(c−2d−1)Δ∑i=1∏n(mi−dΔi)[gcd(Δ1...n)=1]=d∑(c−2d−1)l∑μ(l)Δ∑(i=1∏nmi−dlΔi)=T∑i=1∏n(j∑mi/Tmi−Tj)l∣T∑μ(l)(c−2d−1)
對前面整除分塊(O(nM))段,每一段是關於 T 的 n 次多項式 f(T),可以 O(n2) 求得第 k 項的係數,所以現在就是要求
T=l∑rcoefk(Tkl∣T∑μ(l)(c−2d−1))
後面可以 O(ncM+cMlogM) 預處理得到,詢問的複雜度是 O(Tn3M)
#include<bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
typedef long long ll;
cs int Mod = 10007;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
void Add(int &a, int b){ a = add(a,b); }
void Dec(int &a, int b){ a = dec(a,b); }
void Mul(int &a, int b){ a = mul(a,b); }
int ksm(int a, int b){ int as=1; for(;b;b>>=1,Mul(a,a)) if(b&1) Mul(as,a); return as; }
cs int N = 1e5 + 50;
int T, n, c, a[20];
int f[20][N], prm[N], pc, mu[N]; bool isp[N];
int fc[N], ifc[N], pw[20][12][N];
void fc_init(int n){
fc[0]=fc[1]=ifc[0]=ifc[1]=1;
for(int i=2; i<=n; i++) fc[i]=mul(fc[i-1],i);
ifc[n]=ksm(fc[n],Mod-2);
for(int i=n-1;i>=2;i--) ifc[i]=mul(ifc[i+1],i+1);
}
int C(int n, int m){ if(n<0||m<0||n<m) return 0; return mul(fc[n],mul(ifc[n-m],ifc[m])); }
int binom(int n, int m){
if(n<Mod&&m<Mod) return C(n,m);
return mul(C(n%Mod,m),binom(n/Mod,m/Mod));
}
void pre_work(int n){
mu[1]=1; for(int i=2; i<=n; i++){
if(!isp[i]) prm[++pc]=i, mu[i]=-1;
for(int j=1; j<=pc&&prm[j]*i<=n; ++j){
isp[prm[j]*i]=1;
if(i%prm[j]==0) break;
mu[i*prm[j]]=-mu[i];
}
} for(int c=0; c<=18; c++){
for(int i=1; i<=n; i++) f[c][i]=binom(i-1,c);
for(int i=n; i>=1; i--)
for(int j=i+i; j<=n; j+=i)if(mu[j/i]){
if(mu[j/i]>0) Add(f[c][j],f[c][i]);
else Dec(f[c][j],f[c][i]);
}
}
for(int i=1; i<=n; i++)
for(int j=0; j<=18; j++)
for(int c=0,mt=1; c<=11; c++,Mul(mt,i))
pw[j][c][i]=add(pw[j][c][i-1],mul(f[j][i],mt));
}
int sub(int l, int r){ return ((ll)(l+r)*(r-l+1)>>1)%Mod; }
int calc(int l, int r){
static int dp[20];
for(int i=0; i<=n; i++) dp[i]=0; dp[0]=1;
for(int i=1; i<=n; i++)
for(int j=i; j>=0; j--){
Mul(dp[j],mul(a[i],a[i]/l));
Dec(dp[j],mul(dp[j-1],sub(1,a[i]/l)));
} int ans=0;
for(int i=0; i<=n; i++)
Add(ans,mul(dp[i],dec(pw[c-2][i][r],pw[c-2][i][l-1])));
return ans;
}
void Main(){
scanf("%d%d",&n,&c); int m=1e5;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]),m=min(m,a[i]);
int Ans=0;
for(int l=1,r;l<=m;l=r+1){
r=m; for(int i=1; i<=n; i++)
r=min(r,a[i]/(a[i]/l));
Add(Ans,calc(l,r));
} cout<<Ans<<'\n';
}
int main(){
#ifdef FSYolanda
freopen("1.in","r",stdin);
#endif
scanf("%d",&T);
fc_init(Mod-1); pre_work(1e5);
while(T--) Main();
return 0;
}