web-dev-qa-db-ja.com

数と素因数の関係の最大除数

質問は次のとおりです。2つの数値nとkが与えられます。区間[1、n]の各数値について、タスクはkで割り切れない最大の除数を計算することです。これらすべての約数の合計を出力します。注:kは常に素数です。 t = 3 * 10 ^ 5,1 <= n <= 10 ^ 9、2 <= k <= 10 ^ 9

質問に対する私のアプローチ:1からnの範囲内のすべてのiについて、必要な除数はi自体であり、そのiがkの倍数でない場合のみです。そのiがkの倍数である場合、数値の最大の約数を見つけてkと一致させる必要があります。それが一致しない場合は、この除数が私の答えです。そうでなければ、2番目に大きい除数が私の答えです。

たとえば、n = 10とk = 2の場合、1から10の範囲のすべてのiに必要な約数は1、1、3、1、5、3、7、1、9、5です。これらの約数の合計は36です。つまりans = 36です。

私のコードは、いくつかのテストケースでは機能し、一部のテストケースでは失敗しました。

#include<bits/stdc++.h>
using namespace std;
#define ll long long int

ll div2(ll n, ll k) {
if (n % k != 0 || n == 1) {
    return n;
}

else {
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            ll aa = n / i;
            if (aa % k != 0) {
                return aa;
            }
        }
    }
}
return 1;
}



int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;

while (t--) {
    ll n, k;
    cin >> n >> k;
    ll sum = 0, pp;

    for (pp = 1; pp <= n; pp++) {
        //cout << div2(pp, k);
        sum = sum + div2(pp, k);
    }
    cout << sum << '\n';
 }

 }

私のテストケースの一部が時間制限を超えているため、誰かが私が間違っているところを助けたり、この質問をするためのいくつかのより速いロジックを提案したりできますか?

すべての可能な説明を調べた後、コードを次のように変更します。

#include<bits/stdc++.h>
using namespace std;
#define ll long long int

int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;

while (t--) {
    ll n, i;
    ll k, sum;
    cin >> n >> k;

    sum = (n * (n + 1)) / 2;

    for (i = k; i <= n; i = i + k) {
        ll dmax = i / k;

        while (dmax % k == 0) {
            dmax = dmax / k;
        }
        sum = (sum - i) + dmax;

    }
    cout << sum << '\n';

}

}

しかし、それでも3つのテストケースでTIME LIMIT EXCEEDを与えています。誰か助けてください。

5
sukesh

このようなものはOne Lynerが意味するものなのだろうか。

(このコードには2つのエラーがあり、コメントで説明されています。また、One Lynerの新しいコードで説明できます。)

C++コード:

#include <vector>
#include <iostream>
using namespace std;
#define ll long long int

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;

    while (t--) {
        ll n;
        ll k, _k, result;
        vector<ll> powers;
        cin >> n >> k;

        result = n * (n + 1) / 2;
        _k = k;

        while (_k <= n) {
            powers.Push_back(_k);
            _k = _k * k;
        }

        for (ll p : powers) {
            ll num_js = n / p;
            result -= num_js * (num_js + 1) / 2 * (p - 1);
            int i = 0;
            while (p * powers[i] <= n) {
                result += powers[i] * (p - 1);
                i = i + 1;
            }
        }

        cout << result << '\n';
    }
}
0