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

2024-01-30 00:58

本文主要是介绍【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 FSYolandafreopen("1.in","r",stdin);#endifscanf("%d",&T);fc_init(Mod-1); pre_work(1e5);while(T--) Main();return 0;
}

这篇关于【WC2014】时空穿梭(莫比乌斯反演)(组合数学)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/658654

相关文章

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

hdu4869(逆元+求组合数)

//输入n,m,n表示翻牌的次数,m表示牌的数目,求经过n次操作后共有几种状态#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#includ

uva 10014 Simple calculations(数学推导)

直接按照题意来推导最后的结果就行了。 开始的时候只做到了第一个推导,第二次没有继续下去。 代码: #include<stdio.h>int main(){int T, n, i;double a, aa, sum, temp, ans;scanf("%d", &T);while(T--){scanf("%d", &n);scanf("%lf", &first);scanf

uva 10025 The ? 1 ? 2 ? ... ? n = k problem(数学)

题意是    ?  1  ?  2  ?  ...  ?  n = k 式子中给k,? 处可以填 + 也可以填 - ,问最小满足条件的n。 e.g k = 12  - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 with n = 7。 先给证明,令 S(n) = 1 + 2 + 3 + 4 + 5 + .... + n 暴搜n,搜出当 S(n) >=

uva 11044 Searching for Nessy(小学数学)

题意是给出一个n*m的格子,求出里面有多少个不重合的九宫格。 (rows / 3) * (columns / 3) K.o 代码: #include <stdio.h>int main(){int ncase;scanf("%d", &ncase);while (ncase--){int rows, columns;scanf("%d%d", &rows, &col

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

hdu6053 TrickGCD 莫比乌斯反演

TrickGCD Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Problem Description You are given an array  A  , and Zhu wants to know there are how many d

Go组合

摘要 golang并非完全面向对象的程序语言,为了实现面向对象的继承这一神奇的功能,golang允许struct间使用匿名引入的方式实现对象属性方法的组合 组合使用注意项 使用匿名引入的方式来组合其他struct 默认优先调用外层方法 可以指定匿名struct以调用内层方法 代码 package mainimport ("fmt")type People struct{}type Pe

CSP-J基础之数学基础 初等数论 一篇搞懂(一)

文章目录 前言声明初等数论是什么初等数论历史1. **古代时期**2. **中世纪时期**3. **文艺复兴与近代**4. **现代时期** 整数的整除性约数什么样的整数除什么样的整数才能得到整数?条件:举例说明:一般化: 判断两个数能否被整除 因数与倍数质数与复合数使用开根号法判定质数哥德巴赫猜想最大公因数与辗转相除法计算最大公因数的常用方法:举几个例子:例子 1: 计算 12 和 18