版权声明:欢迎转载(请附带原链接)ヾ(๑╹◡╹)ノ" https://blog.csdn.net/corsica6/article/details/85070333
传送门:bzoj3434
题解
枚举每一维的极差 ,设 ,则这条直线上最多可以选出 个整点(不包含起点)。
则
转成枚举
莫比乌斯反演一下
设 ,得到
可以 预处理。
在 一定时, 是一个关于 的 次多项式,所以 分块,每次 暴力处理 的系数 :
预处理出 的前缀和即可。
复杂度:
代码
#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;
}