*PS:突然被小學數學弄得懷疑人生(⊙_⊙)…老師等等我ヾ(>Д<;))))…..
先科普一下
(百度百科)
整除 [zhěng chú]
若整數a除以非零整數b,商爲整數,且餘數[1] 爲零, 我們就說a能被b整除(或說b能整除a),a爲被除數,b爲除數,即b|a(“|”是整除符號),讀作“b整除a”或“a能被b整除”。a叫做b的倍數,b叫做a的約數(或因數)。整除屬於除盡的一種特殊情況。
也就是 x%(a*b)== 0 。
這裏注意有序對( a,b )是想表達(a,b)和(b,a)是不同的 並不是a < b 或者是 b < a qwq
換個思路 x/(a*b)=c , 即 x= a * b * c ;
所以求f[x]時我們可以固定 a , b 來找 c 。
發現對於一組滿足條件的(a,b,c),若其中的任意兩個數相同對答案的貢獻爲3,全都相同貢獻爲1,全都不同貢獻爲6(3!)。
因此枚舉 a 來計算重複時的情況(即不同的 (a,b,c) 的數量),枚舉a,b來計算互不重複時的情況。(爲避免重複計算,規定a<=b<=c ,故 1<=a<=三次根下(N) , a<=b<=根號(n/a))
並且我們發現 n /(a*a)就是 1~n 中滿足任意兩個數相同時的(a,b,c)的數量之和,n/(a *b)-b 就是1~n中滿足三個數各不相同時的數量之和(-b是去掉前面兩個數重複的情況)。 所以並不需要從1 for 到 n。
代碼
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
long long N,ans=0,cnt;
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%lld",&N);
cnt=0;
for(long long a=1;(a*a)<=N;++a) // 兩個數相同
{
cnt+=N/(a*a);
if(a*a*a<=N) --cnt,++ans; // 三個數相同
}
ans+=cnt*3;
cnt=0;
for(long long a=1;(a*a)<=N;++a)
for(long long b=a+1;(b*b*a)<=N;++b) // 互不相同
cnt+=N/(a*b)-b;
ans+=cnt*6;
printf("%lld",ans);
return 0;
}