貝殼找房算數(中等)
阿新 • • 發佈:2019-01-09
描述
貝殼找房力求為每位使用者找到滿意的房子,最近貝殼找房通過大資料得出下面的一個結論,
求滿足0<i,j<=n,f(i) * f(j)>0,且0 < gcd(f(i),f(j)) <= k的數對 (i,j)的數量,其中滿足條件的對數就是可以滿足某位使用者的房源數目。
其中 f(x)表示 x 所有數位的積,比如 f(124)=1 * 2 * 4 = 8.
因答案很大,請求出其在模 998244353意義下的結果。其中 gcd(x, y)表示x和y的最大公約數。
提示: 其中 (1,2), (2,1)算是兩種情況。
輸入格式
一行兩個正整數,分別表示 n和k。
保證1<=n<=1e6,1<=k<=1e18。
輸出格式
一個整數表示答案。
樣例輸入
9 5
樣例輸出
77
思路
對於數位積相同的可以只算一次,用map存起來個數,這樣就可以將複雜度壓下來了。
程式碼
#include<bits/stdc++.h> #pragma warning(disable:4786) #define ll long long using namespace std; inline ll hh(ll i){ //求數位積 ll temp=1ll; while(i){ temp*=(i%10); i/=10; } return temp; } int main(){ //freopen("2.txt", "r", stdin); ll n, k; scanf("%lld%lld", &n, &k); ll ans =0; map<ll,ll>mp; map<ll,ll>::iterator it1,it2; for(ll i=1;i<=n;i++){ //一個個的求出數位積,放到map裡 ll temp=hh(i); if(temp!=0)mp[temp]++; } for(it1=mp.begin();it1!=mp.end();it1++){ //對於數位積,來個二重迴圈計算 for(it2=it1;it2!=mp.end();it2++){ if(__gcd((*it1).first,(*it2).first)<=k){ //通過algorithm裡面的__gcd直接求公約數 ll temp=(*it1).second * (*it2).second ; ans +=temp; ans %= 998244353; if(it1 != it2)ans +=temp; //不是一樣的,算兩次 ans %= 998244353; } } } printf("%lld\n",ans); }