【WC2014】时空穿梭(莫比乌斯反演)(组合数学)

传送门

  • 考虑枚举各维最大最小坐标的差量 Δ i \Delta_i Δi,可以写出式子: A n s = ∑ Δ ( g c d ( Δ 1... n ) − 1 c − 2 ) ∏ i = 1 n ( m i − Δ i ) = ∑ d ( d − 1 c − 2 ) ∑ Δ ∏ i = 1 n ( m i − d Δ i ) [ g c d ( Δ 1... n ) = 1 ] = ∑ d ( d − 1 c − 2 ) ∑ l μ ( l ) ∑ Δ ( ∏ i = 1 n m i − d l Δ i ) = ∑ T ∏ i = 1 n ( ∑ j m i / T m i − T j ) ∑ l ∣ T μ ( l ) ( d − 1 c − 2 ) Ans=\sum_{\Delta}\binom{gcd(\Delta_{1...n})-1}{c-2}\prod_{i=1}^n (m_i-\Delta_i)\\ =\sum_d\binom{d-1}{c-2}\sum_{\Delta}\prod_{i=1}^n (m_i-d\Delta_i)[gcd(\Delta_{1...n})=1]\\=\sum_d\binom{d-1}{c-2}\sum_{l}\mu(l)\sum_{\Delta}(\prod_{i=1}^nm_i-dl\Delta_i)\\ =\sum_{T}\prod_{i=1}^n(\sum_{j}^{m_i/T}m_i-Tj)\sum_{l|T}\mu(l)\binom{d-1}{c-2} Ans=Δ(c2gcd(Δ1...n)1)i=1n(miΔi)=d(c2d1)Δi=1n(midΔi)[gcd(Δ1...n)=1]=d(c2d1)lμ(l)Δ(i=1nmidlΔi)=Ti=1n(jmi/TmiTj)lTμ(l)(c2d1)
    对前面整除分块( O ( n M ) O(n\sqrt M) O(nM ))段,每一段是关于 T T T n n n 次多项式 f ( T ) f(T) f(T),可以 O ( n 2 ) O(n^2) O(n2) 求得第 k k k 项的系数,所以现在就是要求
    ∑ T = l r c o e f k ( T k ∑ l ∣ T μ ( l ) ( d − 1 c − 2 ) ) \sum_{T=l}^rcoef_k (T^k\sum_{l|T}\mu(l)\binom{d-1}{c-2}) T=lrcoefk(TklTμ(l)(c2d1))
    后面可以 O ( n c M + c M log ⁡ M ) O(ncM+cM\log M) O(ncM+cMlogM) 预处理得到,询问的复杂度是 O ( T n 3 M ) O(Tn^3\sqrt M) 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])));//,cout<<dec(pw[c-2][i][r],pw[c-2][i][l-1])<<" ";cout<<endl;
//	cout<<"calc "<<l<<" "<<r<<endl;
//	for(int i=0; i<=n; i++) cout<<dp[i]<<" ";cout<<endl;
//	cout<<endl<<ans<<endl;
	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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值