Challenge: Tile Painting: Revisited!

Subdomeniu: Combinatorics (combinatorics)

Scor cont: 70.0 / 70

Submission status: Accepted

Submission score: 1.0

Submission ID: 464757996

Limbaj: cpp14

Link challenge: https://www.hackerrank.com/challenges/tile-painting-revisited/problem

Cerinta

Nikita has a row of $N$ white tiles indexed from $1$ to $N$. This time, she's painting them green! 

Find the number of ways Nikita can paint certain tiles in green so that the indices of the green tiles form an [Arithmetic Progression](https://en.wikipedia.org/wiki/Arithmetic_progression). As this value can be quite large, your answer must be modulo $(10^9 + 7)$.

**Note:** Nikita must paint *at least* $1$ tile.

Input Format

The first line contains a single integer, $T$, denoting the number of test cases.	
Each test case consists of a single line containing an integer, $N$, denoting the length of row of tiles.

Output Format

On a new line for each test case, print the number of ways Nikita can paint her white tiles green so that the indices of the green tiles form an [Arithmetic Progression](https://en.wikipedia.org/wiki/Arithmetic_progression). Because this number can be quite large, your answer must be modulo $(10^9+7)$.

Constraints

* $1 \le T \le 10$
* $1 \le N \le 10^{10}$

**Scoring**

* $1 \le N \le 2000$ for $20\%$ of test data.
* $1 \le N \le 10^5$ for $50\%$ of test data.
* $1 \le N \le 10^{10}$ for $100\%$ of test data.

Cod sursa

#include <bits/stdc++.h>
using namespace std;

using i128 = __int128_t;
static const long long MOD = 1000000007LL;

static inline long long modNorm(long long x) {
    x %= MOD;
    if (x < 0) x += MOD;
    return x;
}

static inline long long sumRangeMod(long long l, long long r) {
    // (l + ... + r) mod MOD
    i128 cnt = (i128)(r - l + 1);
    i128 s = (i128)(l + r) * cnt / 2;
    return (long long)(s % MOD);
}

long long solveOne(long long N) {
    if (N == 1) return 1;

    long long M = N - 1;

    long long C = 0; // sum floor(M/a)
    long long T = 0; // sum a * q(q+1)/2

    for (long long l = 1; l <= M;) {
        long long q = M / l;
        long long r = M / q;

        long long cntMod = (r - l + 1) % MOD;
        C = (C + (i128)(q % MOD) * cntMod) % MOD;

        long long sumA = sumRangeMod(l, r);
        long long triQ = (i128)q * (q + 1) / 2 % MOD;
        T = (T + (i128)sumA * triQ) % MOD;

        l = r + 1;
    }

    long long S = modNorm((i128)((M + 1) % MOD) * C % MOD - T); // S = sum_{t=1..M} D(t)
    long long ans = modNorm((N % MOD) + S);
    return ans;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;
    while (T--) {
        long long N;
        cin >> N;
        cout << solveOne(N) << '\n';
    }

    return 0;
}
HackerRank Combinatorics – Tile Painting: Revisited!