【蓝桥杯】 2018年国赛 矩阵求和
生活随笔
收集整理的這篇文章主要介紹了
【蓝桥杯】 2018年国赛 矩阵求和
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目
題目:
經過重重筆試面試的考驗,小明成功進入 Macrohard 公司工作。
今天小明的任務是填滿這么一張表:
表有 n 行 n 列,行和列的編號都從1算起。
其中第 i 行第 j 個元素的值是 gcd(i, j)的平方,
gcd 表示最大公約數,以下是這個表的前四行的前四列:
1 1 1 1
1 4 1 4
1 1 9 1
1 4 1 16
小明突然冒出一個奇怪的想法,他想知道這張表中所有元素的和。
由于表過于龐大,他希望借助計算機的力量。
題解:
已知可以用歐拉函數和莫比烏斯反演來做
題目其實就是問
歐拉函數:
莫比烏斯反演:
代碼:
#include<bits/stdc++.h> using namespace std; const int maxn=1e7+9; typedef long long ll; bool vis[maxn]; ll prime[maxn]; ll phi[maxn]; ll s[maxn];const int mod=1e9+7; void Euler(int n) {phi[1]=1;int cnt=0;for(int i=2;i<=n;i++){if(!vis[i]){prime[cnt++]=i;phi[i]=i-1;}for(int j=0;j<cnt&&i*prime[j]<=n;j++){vis[prime[j]*i]=1;if(i%prime[j]){phi[i*prime[j]]=phi[i]*(prime[j]-1);}else {phi[i*prime[j]]=phi[i]*prime[j];break;}} }s[1]=phi[1];for(int i=2;i<n;i++){s[i]=s[i-1]+2*phi[i];} } int main() {int n;Euler(maxn);ll sum=0;while(cin>>n){sum=0;for(ll i=1;i<=n;i++)sum=(sum+s[n/i]%mod*i%mod*i%mod)%mod;cout<<sum<<endl;} } #include<bits/stdc++.h> using namespace std; typedef long long int ll; const int mod=1e9+7; const int maxn = 10000000 + 10; ll mu[maxn], vis[maxn], prim[maxn]; ll cnt = 0; //素數的個數 ll d[maxn]; ll sum(int n) {ll ans=0;for(int l=1,r;l<=n;l=r+1) //整除分塊 {r=n/(n/l);ans=(ans+(mu[r]-mu[l-1]+mod)%mod*((ll)n/l)%mod*((ll)n/l)%mod)%mod;}return ans; } void get_mu(int n) {mu[1] = 1;for (int i = 2; i <= n; i++){if (!vis[i]) { prim[++cnt] = i; mu[i] = -1; }for (int j = 1; j <= cnt && prim[j] * i <= n; j++){vis[prim[j] * i] = 1;if (i%prim[j] == 0)break;else mu[i*prim[j]] = -mu[i];}}for(int i=1;i<=n;i++){d[i]=((ll)i*i)%mod;}for(int i=2;i<=n;i++){d[i]=(d[i-1]+d[i])%mod; //d的前綴和 mu[i]=(mu[i-1]+mu[i]+mod)%mod; //mu的前綴和 }ll ans=0;for(int l=1,r;l<=n;l=r+1) //整除分塊 {r=n/(n/l);ans=(ans+(ll)(d[r]-d[l-1]+mod)%mod*(ll)sum(n/l)%mod)%mod;}cout<<ans<<endl; } int main() {int n;cin>>n;get_mu(n);return 0; }總結
以上是生活随笔為你收集整理的【蓝桥杯】 2018年国赛 矩阵求和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 东风汽车全新品牌“奕派”发布,首款车型
- 下一篇: 关于善意的谎言的名言 有哪些呢