1. 程式人生 > >noip模擬賽 a

noip模擬賽 a

stream name temp 模擬 algorithm pan ios image sca

技術分享

分析:f(n)就是問有多少對a*b*c = n,如果是Σf(i),那就是問有多少對a*b*c <= n.

這道題和之前做過的一道數三角形的題差不多:傳送門,先假設一下a <= b <= c,=和<不好同時處理,那麽我們就分開處理,先處理<的情況,a <= 三次根號下n,b * b <= n / a,然後c就可以利用範圍統計出來了.因為這裏強行規定了a < b < c,所以最後還要乘上3個數的排列數6.

接下來處理有兩個數相等的情況,枚舉相等的那個數,還是根據另外一個數的範圍來求方案數,所得答案乘上3個數中選2個相同的數的方案數就可以了,但是這樣做有一個問題,就是可能會有a*a*a這種情況,不管選哪兩個數就是同一種情況,我們在處理的時候要把這個答案給減掉,最後在來算3個數相同的情況.

感覺鐘長者出的這類數學題都有一個共同的特點:利用取值範圍求方案數.一般的解法就是先規定一個大小關系,求出方案數後乘以排列數,然後去重.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

ll n, temp, ans;

int main()
{
    scanf("%lld", &n);
    for (ll a = 1; a * a <= (n / a); a++)
        
for (ll b = a + 1; b * b <= (n / a); b++) temp += n / (a * b) - b; temp *= 6; ans += temp; temp = 0; for (ll a = 1; (a * a) <= n; a++) { temp += n / (a * a); if (a * a <= n / a) temp--; } temp *= 3; ans += temp; for (ll a = 1
; a * a <= n / a; a++) ans++; printf("%lld\n", ans); return 0; }

noip模擬賽 a