Soluție HackerRank pentru Fun With Series, subdomeniul Algebra, în C++14. Include cerința formatată, exemple, explicația pașilor și cod sursă.

  • Problemă: Fun With Series
  • Domeniu: Algebra
  • Limbaj: C++14

Challenge: Fun With Series

Subdomeniu: Algebra (algebra)

Scor cont: 75.0 / 75

Submission status: Accepted

Submission score: 1.0

Submission ID: 464779714

Limbaj: cpp14

Link challenge: https://www.hackerrank.com/challenges/fun-with-series/problem

Cerință

Julia found a series, G, defined as:
G_n = begin{cases}0 &n = 01 &n = 1a× G_n-1+b× G_n-2 & ngt 1 text{ and } a, b ≥ 1 end{cases}

For some integer p (where p gt 0), she finds p + 2 integers, c_0, c_1, c_2, …, c_p+1, such that L(p, n) = 0 holds for all integers n (where n gt p):
L(p, n) = ∑_i = 0^p + 1 c_i ≤ft(G_n-iright)^p

She realized that the values of c_i are not unique, so she only considers the tuple (c_0, c_1, …, c_p+1) such that c_0 gt 0 and c_0 is minimal. It is guaranteed that when c_0 gt 0 and c_0 is minimal, there exists only one tuple (c_0, c_1, …, c_p+1).

Next, she defines S_1(p) and S_2(p):
S_1(p) = ≤ft( ∑ c_i right) % (10^9+7) forall c_i > 0
S_2(p) = ≤ft( ∑ ≤ft|c_i right| right) % (10^9+7) forall c_i < 0

She then finds the following interesting property of c_i:
prod_i=0^p+1 ≤ft|c_iright| = w × prod_i=2^p+1 G_i^z_i

where w and z_i are integers such that:

* w ne 0
* z_2 + 2p = z_p + 1 + 2
* ∑limits_i=2^p+1 z_i = p

Julia wants you to answer q queries in the following forms:

1. `1 l r`: Using S_1(p) and S_2(p), print three space-separated integers denoting the respective values of Count_1, Count_2, and Count_3 where:

* Count_1 is the total number of possible values of p (where l ≤ p ≤ r) such that S_1(p) gt S_2(p).
* Count_2 is the total number of possible values of p (where l ≤ p ≤ r) such that S_1(p) lt S_2(p).
* Count_3 is the total number of possible values of p (where l ≤ p ≤ r) such that S_1(p) = S_2(p).

2. `2 p u v`: Find the value of S modulo ≤ft(10^9+7right):
S = ≤ft(prod_i=u^vG_iright)^≤ft(w + phiright) text{, where } phi=≤ft|∑_i=u^v z_iright|

Input Format

The first line contains three space-separated integers describing the respective values of a, b, and q.
Each line i of the q subsequent lines contains three or four space-separated values denoting a query asked by Julia.

Output Format

Print q lines of output where each line i denotes the answer to query i.

Constraints

* 1 ≤ a, b ≤ 10^6
* 1 ≤ q ≤ 5 × 10^4
* 1 ≤ l ≤ r ≤ 10^3
* 1 ≤ p ≤ 10^6
* 2 ≤ u ≤ v ≤ p + 1

Cod sursă

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

static const long long MOD = 1000000007LL;

struct Query {
    int type;
    long long x, y, z; // type1: x=l, y=r; type2: x=p, y=u, z=v
};

static long long modPow(long long a, long long e, long long mod) {
    a %= mod;
    long long r = 1 % mod;
    while (e > 0) {
        if (e & 1) r = (__int128)r * a % mod;
        a = (__int128)a * a % mod;
        e >>= 1;
    }
    return r;
}

static long long modInv(long long a) {
    return modPow(a, MOD - 2, MOD);
}

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

    long long a, b;
    int q;
    cin >> a >> b >> q;

    vector<Query> queries;
    queries.reserve(q);

    int maxR = 0;
    int maxP = 0;
    int maxV = 1;

    for (int i = 0; i < q; i++) {
        int t;
        cin >> t;
        if (t == 1) {
            long long l, r;
            cin >> l >> r;
            queries.push_back({t, l, r, 0});
            maxR = max<long long>(maxR, r);
        } else {
            long long p, u, v;
            cin >> p >> u >> v;
            queries.push_back({t, p, u, v});
            maxP = max<long long>(maxP, p);
            maxV = max<long long>(maxV, v);
        }
    }

    int N = maxR + 1;
    N = max(N, 1);

    int G = max(maxV, N + 2);

    vector<int> g(G + 1, 0);
    g[0] = 0;
    g[1] = 1;
    for (int i = 2; i <= G; i++) {
        long long val = ((__int128)(a % MOD) * g[i - 1] + (__int128)(b % MOD) * g[i - 2]) % MOD;
        g[i] = (int)val;
    }

    vector<long long> prefProd(G + 1, 1);
    for (int i = 1; i <= G; i++) {
        prefProd[i] = (prefProd[i - 1] * g[i]) % MOD;
    }

    vector<vector<int>> tria(N + 2, vector<int>(N + 2, 0));

    if (N >= 1) {
        tria[1][0] = 1;
        tria[1][1] = 1;
    }

    for (int i = 2; i <= N; i++) {
        tria[i][0] = 1;
        long long rpow = 1;
        for (int j = 1; j <= i; j++) {
            long long term1 = ((__int128)tria[i - 1][j - 1] * g[i - j + 1]) % MOD;
            term1 = (term1 * rpow) % MOD;

            long long term2 = ((__int128)tria[i - 1][j] * g[j - 1]) % MOD;
            term2 = (term2 * (b % MOD)) % MOD;

            tria[i][j] = (int)((term1 + term2) % MOD);

            rpow = (rpow * (b % MOD)) % MOD;
        }
    }

    vector<int> pref0(N + 2, 0), pref1(N + 2, 0), pref2(N + 2, 0);

    auto isSn = [](int j) -> bool {
        int m = j & 3;
        return (m == 1 || m == 2);
    };

    for (int i = 1; i <= N; i++) {
        int sp = 0, sn = 0;
        for (int j = 0; j <= i; j++) {
            if (isSn(j)) {
                sn += tria[i][j];
                if (sn >= MOD) sn -= MOD;
            } else {
                sp += tria[i][j];
                if (sp >= MOD) sp -= MOD;
            }
        }
        pref0[i] = pref0[i - 1];
        pref1[i] = pref1[i - 1];
        pref2[i] = pref2[i - 1];

        if (sn == sp) pref1[i]++;
        else if (sn > sp) pref2[i]++;
        else pref0[i]++;
    }

    for (auto &qq : queries) {
        if (qq.type == 1) {
            int L = (int)qq.x + 1;
            int R = (int)qq.y + 1;
            L = max(L, 1);
            R = min(R, N);

            int ans0 = pref0[R] - pref0[L - 1];
            int ans2 = pref2[R] - pref2[L - 1];
            int ans1 = pref1[R] - pref1[L - 1];

            cout << ans0 << " " << ans2 << " " << ans1 << "\n";
        } else {
            long long p = qq.x;
            int u = (int)qq.y;
            int v = (int)qq.z;

            long long prod_uv = prefProd[v] * modInv(prefProd[u - 1]) % MOD;

            long long wp = p * (p + 1) * (p + 2) / 6;

            long long w = modPow((b % (MOD - 1) + (MOD - 1)) % (MOD - 1), wp, MOD - 1);

            long long phi = 1LL * v * (v - 1) - 1LL * (u - 1) * (u - 2) - 1LL * p * (v - u + 1);
            phi = llabs(phi);
            phi = (phi + w) % (MOD - 1);

            cout << modPow(prod_uv, phi, MOD) << "\n";
        }
    }

    return 0;
}
HackerRank Algebra – Fun With Series