codeforces 10 C. Digital Root 數學
阿新 • • 發佈:2021-10-22
有點像以前做數學新定義,做完看題解才知道真有這公式。
數字根:任何一個數字的數字根等於它%9得到的數,如果是9的倍數的話則為9。
改天沒事再yy顱腔內證明一下..
拿到定義在不知道公式前,通過觀察可以知道1e6的資料不會超過幾次計算就能得到數字根
o(n)就能把它們都求出來了,順便統計一下數字根為i的數有多少個,開個桶排
考慮d(c)=d(d(a)*d(b)),因為值域都不大,列舉d(c),d(a),d(b),求得總數
考慮容斥原理,減去a*b=c的情況,通過觀察發現若a*b=c,則d(c)=d(d(a)*d(b))恆成立
轉化為求abc的對數,其中a*b=c,且c<=n;
剛開始想對範圍內的每一個數求它的因子數,代價太大
然後發現可以反過來列舉因子(這在數論裡挺常見的)
對每個i,ans-n/i即可
---
第一次切cf的c題無論是出思路還是寫程式碼都這麼愜意。。
#include<bits/stdc++.h> using namespace std; unsigned long long cnt[1000]; int chaifen(int x) { int xx=x,ans=0; while(xx>0) { ans+=xx%10; xx/=10; } if(ans>9) { return chaifen(ans); }else return ans; } int main( ) { int n; cin>>n; for(int i=1;i<=n;i++) { int a=chaifen(i); cnt[a]++; } unsigned long long ans=0; for(int k=1;k<=9;k++)//d(c)的值 for(int i=1;i<=9;i++)//d(a) for(int j=1;j<=9;j++)//d(b) { if(chaifen(i*j)==k) { ans+=cnt[i]*cnt[j]*cnt[k]; } } for(int i=1;i<=n;i++) { ans-=n/i; } cout<<ans<<endl; }