1. 程式人生 > 其它 >codeforces 10 C. Digital Root 數學

codeforces 10 C. Digital Root 數學

有點像以前做數學新定義,做完看題解才知道真有這公式。

數字根:任何一個數字的數字根等於它%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; }