NOIP 模擬 $38\; \rm b$
阿新 • • 發佈:2021-08-13
題解
題解 \(by\;zj\varphi\)
考慮轉化問題,將計算最大公約數換為列舉最大公約數。
設 \(sum_i\) 為最大公約數為 \(i\) 的方案數,可以容斥求解,\(sum_i=f_i-\sum_{j=2}^{j*i\le mx} sum_{j*i}\)。
\(f_i\) 表示最大公約數是 \(i\) 的倍數的方案數,設 \(g_{i,j}\) 為第 \(i\) 行,倍數為 \(j\) 的有幾個。
最後記得算不選的情況,還要加去一個沒選的情況。
Code
#include<bits/stdc++.h> #define Re register #define ri Re signed #define p(i) ++i namespace IO{ char buf[1<<21],*p1=buf,*p2=buf; #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++ struct nanfeng_stream{ template<typename T>inline nanfeng_stream &operator>>(T &x) { Re bool f=0;x=0;Re char ch=gc(); while(!isdigit(ch)) f|=ch=='-',ch=gc(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=gc(); return x=f?-x:x,*this; } }cin; } using IO::cin; namespace nanfeng{ #define FI FILE *IN #define FO FILE *OUT template<typename T>inline T cmax(T x, T y) {return x>y?x:y;} template<typename T>inline T cmin(T x, T y) {return x>y?y:x;} typedef long long ll; static const int M=1e5+7,N=22,MOD=1e9+7; int cnt[N][M],ct[N][M],sum[M],mx,n,m,ans; inline int main() { //FI=freopen("nanfeng.in","r",stdin); //FO=freopen("nanfeng.out","w",stdout); cin >> n >> m; for (ri i(1);i<=n;p(i)) for (ri j(1),a;j<=m;p(j)) { cin >> a; ++ct[i][a]; mx=cmax(mx,a); } for (ri i(1);i<=n;p(i)) for (ri j(1);j<=mx;p(j)) for (ri k(1);k*j<=mx;p(k)) cnt[i][j]+=ct[i][k*j]; for (ri i(mx);i;--i) { sum[i]=1; for (ri j(1);j<=n;p(j)) sum[i]=(ll)sum[i]*(cnt[j][i]+1)%MOD; sum[i]=(sum[i]-1+MOD)%MOD; if (!sum[i]) continue; for (ri k(2);k*i<=mx;p(k)) sum[i]=(sum[i]-sum[k*i]+MOD)%MOD; ans=(ans+(ll)sum[i]*i%MOD)%MOD; } printf("%d\n",ans); return 0; } } int main() {return nanfeng::main();}