传送门:bzoj3434
题解
枚举每一维的极差 Δ x i \Delta x_i Δxi,设 d = g c d ( Δ x 1 , Δ x 2 , . . . , Δ x n ) d=gcd(\Delta x_1,\Delta x_2,...,\Delta x_n) d=gcd(Δx1,Δx2,...,Δxn),则这条直线上最多可以选出 d d d个整点(不包含起点)。
则
a n s = ∑ Δ x 1 = 1 m 1 ⋯ ∑ Δ x n = 1 m n ( d − 1 c − 2 ) ∏ i = 1 n ( m i − Δ x i ) ans=\sum\limits_{\Delta x_1=1}^{m_1}\dots\sum\limits_{\Delta x_n=1}^{m_n}\dbinom{d-1}{c-2}\prod\limits_{i=1}^n(m_i-\Delta x_i) ans=Δx1=1∑m1⋯Δxn=1∑mn(c−2d−1)i=1∏n(mi−Δxi)
转成枚举 d d d
∑ d = 1 m ( d − 1 c − 2 ) ∑ Δ x 1 = 1 ⌊ m 1 d ⌋ ⋯ ∑ Δ x n = 1 ⌊ m n d ⌋ [ ( Δ x 1 , Δ x 2 , . . . , Δ x n ) = 1 ] ∏ i = 1 n ( m i − d Δ x i ) \sum\limits_{d=1}^m\dbinom{d-1}{c-2}\sum\limits_{\Delta x_1=1}^{\lfloor \frac{m_1}{d}\rfloor}\dots\sum\limits_{\Delta x_n=1}^{\lfloor \frac{m_n}{d}\rfloor}[(\Delta x_1,\Delta x_2,...,\Delta x_n)=1]\prod\limits_{i=1}^n(m_i-d\Delta x_i) d=1∑m(c−2d−1)Δx1=1∑⌊dm1⌋⋯Δxn=1∑⌊dmn⌋[(Δx1,Δx2,...,Δxn)=1]i=1∏n(mi−dΔxi)
莫比乌斯反演一下
∑ d = 1 m ( d − 1 c − 2 ) ∑ k = 1 ⌊ m d ⌋ μ ( k ) ∑ Δ x 1 = 1 ⌊ m 1 d k ⌋ ⋯ ∑ Δ x n = 1 ⌊ m n d k ⌋ ∏ i = 1 n ( m i − d k Δ x i ) \sum\limits_{d=1}^m\dbinom{d-1}{c-2}\sum\limits_{k=1}^{\lfloor\frac md \rfloor}\mu (k)\sum\limits_{\Delta x_1=1}^{\lfloor \frac{m_1}{dk}\rfloor}\dots\sum\limits_{\Delta x_n=1}^{\lfloor \frac{m_n}{dk}\rfloor}\prod\limits_{i=1}^n(m_i-dk\Delta x_i) d=1∑m(c−2d−1)k=1∑⌊dm⌋μ(k)Δx1=1∑⌊dkm1⌋⋯Δxn=1∑⌊dkmn⌋i=1∏n(mi−dkΔxi)
设 T = d k T=dk T=dk,得到
∑ T = 1 m ( ∏ i = 1 n ∑ Δ x i = 1 ⌊ m i T ⌋ ( m i − T Δ x i ) ) ∑ d ∣ T ( d − 1 c − 2 ) μ ( T d ) \sum\limits_{T=1}^m(\prod\limits_{i=1}^n\sum\limits_{\Delta x_i=1}^{\lfloor \frac {m_i}{T}\rfloor}(m_i-T\Delta x_i))\sum\limits_{d|T}\binom{d-1}{c-2}\mu(\frac Td) T=1∑m(i=1∏nΔxi=1∑⌊Tmi⌋(mi−TΔxi))d∣T∑(c−2d−1)μ(dT)
G ( T ) = ∑ d ∣ T ( d − 1 c − 2 ) μ ( T d ) G(T)=\sum\limits_{d|T}\binom{d-1}{c-2}\mu(\frac Td) G(T)=d∣T∑(c−2d−1)μ(dT)可以 O ( m l n m ) O(mlnm) O(mlnm)预处理。
F ( T ) = ∏ i = 1 n ∑ Δ x i = 1 ⌊ m i T ⌋ ( m i − T Δ x i ) F(T)=\prod\limits_{i=1}^n\sum\limits_{\Delta x_i=1}^{\lfloor \frac {m_i}{T}\rfloor}(m_i-T\Delta x_i) F(T)=i=1∏nΔxi=1∑⌊Tmi⌋(mi−TΔxi)
= ∏ i = 1 n ( m i ⌊ m i T ⌋ + T ( ⌊ m i T ⌋ + 1 ) ⌊ m i T ⌋ 2 ) \qquad\ =\prod\limits_{i=1}^n(m_i\lfloor\frac {m_i}{T}\rfloor+\dfrac{T(\lfloor\frac {m_i}{T}\rfloor+1)\lfloor\frac {m_i}{T}\rfloor}{2}) =i=1∏n(mi⌊Tmi⌋+2T(⌊Tmi⌋+1)⌊Tmi⌋)
在 ⌊ m i T ⌋ \lfloor\frac {m_i}{T}\rfloor ⌊Tmi⌋一定时, F ( T ) F(T) F(T)是一个关于 T T T的 n n n次多项式,所以 n m n\sqrt m nm分块,每次 n 2 n^2 n2暴力处理 T i T^i Ti的系数 a i a_i ai:
a n s = ∑ T = 1 m ∑ i = 0 n a i G ( T ) T i ans=\sum\limits_{T=1}^m\sum\limits_{i=0}^na_iG(T)T^i ans=T=1∑mi=0∑naiG(T)Ti
预处理出 G ( T ) T i G(T)T^i G(T)Ti的前缀和即可。
复杂度: O ( m l n l n m + c m ln m + c m n + T n 3 m ) O(m\ ln\ ln m+cm\ln m+cmn+Tn^3\sqrt m) O(m ln lnm+cmlnm+cmn+Tn3m)
代码
#include<bits/stdc++.h>
#define mem(f,x) memset(f,x,sizeof(f))
typedef long long ll;
using namespace std;
const int N=1e5+10,mod=10007;
int tk,mxc,mxm,mn,ans,C[N][21],tmp[12];
int mu[N],g[21][N],f[21][12][N],p[N],num;bool pri[N];
char cp;
inline void rd(int &x)
{
cp=getchar();x=0;
for(;!isdigit(cp);cp=getchar());
for(;isdigit(cp);cp=getchar()) x=x*10+(cp^48);
}
inline void upp(int &x,int y){if(y>x) x=y;}
inline void dnn(int &x,int y){if(y<x) x=y;}
inline void ad(int &x,int y){x+=y;if(x>=mod) x-=mod;}
inline void dc(int &x,int y){x-=y;if(x<0) x+=mod;}
inline int adi(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int dci(int x,int y){x-=y;return x<0?x+mod:x;}
inline void pre()
{
int c,i,j,k,res;mu[1]=1;
for(i=2;i<=mxm;++i){
if(!pri[i]) p[++num]=i,mu[i]=-1;
for(j=1;j<=num && (res=i*p[j])<=mxm;++j){
pri[res]=true;if(i%p[j]==0) break;
mu[res]=-mu[i];
}
}
C[0][0]=1;
for(i=1;i<=mxm;++i){
C[i][0]=1;
for(j=1;j<=mxc;++j) C[i][j]=adi(C[i-1][j-1],C[i-1][j]);
}
for(c=2;c<=mxc;++c){
for(i=1;i<=mxm;++i){
res=C[i-1][c-2];
for(j=1,k=i;k<=mxm;++j,k+=i) if(mu[j])
mu[j]<0?dc(g[c][k],res):ad(g[c][k],res);
}
}
for(c=2;c<=mxc;++c){
for(i=1;i<=mxm;++i){
res=g[c][i];
for(j=0;j<=11;++j){
f[c][j][i]=adi(res,f[c][j][i-1]);
res=(res*i)%mod;
}
}
}
}
struct P{
int n,c,m[12];
inline void init()
{
rd(n);rd(c);upp(mxc,c);
for(int i=1;i<=n;++i){rd(m[i]);upp(mxm,m[i]);}
}
inline void mk(int x)
{
int i,j,a,b;mem(tmp,0);tmp[0]=1;
for(i=1;i<=n;++i){
j=m[i]/x;
a=mod-((ll)j*(j+1)/2)%mod;
if(a==mod) a=0;
b=(ll)j*m[i]%mod;
for(j=n;j;--j) tmp[j]=adi(tmp[j]*b%mod,tmp[j-1]*a%mod);
tmp[0]=tmp[0]*b%mod;
}
}
inline void sol()
{
int i,j,k;ans=0;mn=2e9;
for(i=1;i<=n;++i) dnn(mn,m[i]);
for(i=1;i<=mn;i=j+1){
for(j=mn,k=1;k<=n;++k) dnn(j,m[k]/(m[k]/i));
for(mk(i),k=0;k<=n;++k) ad(ans,tmp[k]*dci(f[c][k][j],f[c][k][i-1])%mod);
}
printf("%d\n",ans);
}
}q[1005];
int main(){
int i,j;rd(tk);
for(i=1;i<=tk;++i) q[i].init();
pre();
for(i=1;i<=tk;++i) q[i].sol();
return 0;
}