列表

详情


NC24664. Hypercube Random Number Generator

描述

As the final project of the Algorithm class, you and Ramen are going to design a new Random Number Generator called Hypercube Random Number Generator(HRNG), which is based on the idea of the hypercube. 

What is a hypercube? The Wikipedia said:
In geometry, a hypercube is an n-dimensional analogue of a square (n = 2) and a cube (n = 3, picture below). It is a closed, compact, convex figure whose 1-skeleton consists of groups of opposite parallel line segments aligned in each of space's dimensions, perpendicular to each other and of the same length.

In the problem, we define a hypercube using a pair , where  is the dimensions of the hypercube and  is the length of each dimension. For example,  is a square which length is 100. Then we set one of its corners as the origin, so we get an -dimensional coordinate system. Each point inside the hypercube can be described as an -tuple like , and a integer point is that a point that . Especially, the origin's coordinate is .

The principle behind the HRNG is pretty easy. We can use a function  to represent it. When we call it using a hypercube, it will randomly choose an integer point inside it with the same probability. Assume the point is , then the HRNG calculates the next value by . For example, if the hypercube is , we may obtain  if the point it randomly choosed is .

In the report section, the teacher asked students to analysis their algorithm. Ramen has done the design work, so the review is your task. As an RNG, it should return each possible values with the same probability. In other words, the math expectation of HRNG should equal to the expected value of the discrete uniform distribution of , i.e., . To measure your work, you need to compute the expected value of HRNG using given hypercube

输入描述

The input contains two integers n, p(1 <= n <= 1e18,1 <= p <= 100), represents the dimension of the hypercube and the length of each dimension.

输出描述

Output the expected value of HRNG in one single line.

To avoid possible errors, if the answer is , you need to output , i.e., , where  is the minimum number that suits .

示例1

输入:

2 100

输出:

199648919

说明:

In the sample test case 1, the expected value is 48.4, which can write as \frac{242}{5}, then we get 242\cdot5^{-1}\equiv 199648919\pmod{998244353}.

示例2

输入:

123456789876543 21

输出:

394865429

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 213ms, 内存消耗: 1000K, 提交时间: 2019-04-14 18:40:25

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 998244353;
struct Mat {
    int n;
    ll a[105][105];
    Mat() { memset(a, 0, sizeof a); }
    void init() { memset(a, 0, sizeof a); for(int i = 1; i <= n; i++) a[i][i] = 1; }
    Mat operator * (const Mat &t) const {
        Mat res; res.n = n;
        for(int k = 1; k <= n; k++)
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= n; j++)
                    res.a[i][j] = (res.a[i][j] + 1ll * a[i][k] * t.a[k][j]) % mod;
        return res;
    }
    Mat operator ^ (ll m) const {
        Mat res; res.n = n; res.init();
        Mat tmp(*this);
        while(m) {
            if(m & 1) res = res * tmp;
            tmp = tmp * tmp;
            m >>= 1;
        }
        return res;
    }
};
ll p, n;
ll qpow(ll x, ll n) {
    ll res = 1;
    while(n) {
        if(n & 1) res = res * x % mod;
        x = x * x % mod;
        n >>= 1;
    }
    return res;
}
int main() {
    cin >> n >> p;
    Mat f, g;
    f.n = g.n = p;
    for(int i = 1; i <= p; i++) f.a[1][i] = 1;
    for(int i = 1; i <= p; i++)
        for(int j = 1; j <= p; j++) {
            int x = i - 1, y = j - 1;
            for(int k = 1; k <= p; k++)
                if(k * x % p == y) {
                    g.a[i][j]++;

                }
        }
    f = f * (g ^ (n - 1));
    ll ans = 0;
    for(int i = 1; i <= p; i++) ans = (ans + 1ll * i * f.a[1][i]) % mod;
    ans = ans * qpow(qpow(p, n), mod - 2) % mod;
    cout << ans << endl;

}

上一题