結果

問題 No.3510 RPS Eliminations
コンテスト
ユーザー はじっこゆーれー
提出日時 2026-04-18 06:13:53
言語 C++23(gnu拡張)
(gcc 15.2.0 + boost 1.89.0)
コンパイル:
g++-15 -O2 -lm -std=gnu++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
TLE  
実行時間 -
コード長 7,661 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 2,522 ms
コンパイル使用メモリ 218,056 KB
実行使用メモリ 131,932 KB
最終ジャッジ日時 2026-04-18 06:14:43
合計ジャッジ時間 14,805 ms
ジャッジサーバーID
(参考情報)
judge1_0 / judge3_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample -- * 1
other AC * 5 TLE * 2 -- * 21
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <iostream>
#include <vector>
#include <string>
using namespace std;
const long long INF = 2000000000000000000LL;
inline long long add(long long a, long long b) {
    long long res = a + b;
    return res >= INF ? INF : res;
}
inline long long mul(long long a, long long b) {
    if (!a || !b) return 0;
    unsigned __int128 res = (unsigned __int128)a * b;
    return res >= INF ? INF : (long long)res;
}
struct Vec {
    long long v[3];
    Vec() { v[0] = v[1] = v[2] = 0; }
    Vec(long long r, long long p, long long s) { v[0] = r; v[1] = p; v[2] = s; }
};
struct Mat {
    long long m[3][3];
    Mat() {
        m[0][0]=m[0][1]=m[0][2]=0;
        m[1][0]=m[1][1]=m[1][2]=0;
        m[2][0]=m[2][1]=m[2][2]=0;
    }
    static Mat identity() {
        Mat res;
        res.m[0][0] = res.m[1][1] = res.m[2][2] = 1;
        return res;
    }
    inline Mat operator*(const Mat& o) const {
        Mat r;
        for (int i = 0; i < 3; ++i) {
            long long m0 = m[i][0], m1 = m[i][1], m2 = m[i][2];
            if (m0) {
                r.m[i][0] = add(r.m[i][0], mul(m0, o.m[0][0]));
                r.m[i][1] = add(r.m[i][1], mul(m0, o.m[0][1]));
                r.m[i][2] = add(r.m[i][2], mul(m0, o.m[0][2]));
            }
            if (m1) {
                r.m[i][0] = add(r.m[i][0], mul(m1, o.m[1][0]));
                r.m[i][1] = add(r.m[i][1], mul(m1, o.m[1][1]));
                r.m[i][2] = add(r.m[i][2], mul(m1, o.m[1][2]));
            }
            if (m2) {
                r.m[i][0] = add(r.m[i][0], mul(m2, o.m[2][0]));
                r.m[i][1] = add(r.m[i][1], mul(m2, o.m[2][1]));
                r.m[i][2] = add(r.m[i][2], mul(m2, o.m[2][2]));
            }
        }
        return r;
    }
};
inline Mat make_matrix(const Vec& A) {
    Mat M;
    M.m[0][0] = A.v[2]; M.m[0][2] = A.v[0];
    M.m[1][1] = A.v[0]; M.m[1][0] = A.v[1];
    M.m[2][2] = A.v[1]; M.m[2][1] = A.v[2];
    return M;
}
inline Vec operator*(const Mat& m, const Vec& v) {
    Vec r;
    r.v[0] = add(mul(m.m[0][0], v.v[0]), add(mul(m.m[0][1], v.v[1]), mul(m.m[0][2], v.v[2])));
    r.v[1] = add(mul(m.m[1][0], v.v[0]), add(mul(m.m[1][1], v.v[1]), mul(m.m[1][2], v.v[2])));
    r.v[2] = add(mul(m.m[2][0], v.v[0]), add(mul(m.m[2][1], v.v[1]), mul(m.m[2][2], v.v[2])));
    return r;
}
struct BIT {
    int n, lg;
    vector<int> tree;
    BIT(int n) : n(n), tree(n + 1, 0) {
        lg = 0;
        while ((1 << (lg + 1)) <= n) lg++;
    }
    inline void add(int i, int delta) {
        for (; i <= n; i += i & -i) tree[i] += delta;
    }
    inline int find_kth(int k) {
        int idx = 0;
        for (int i = lg; i >= 0; i--) {
            int next_idx = idx + (1 << i);
            if (next_idx <= n && tree[next_idx] < k) {
                idx = next_idx;
                k -= tree[idx];
            }
        }
        return idx + 1;
    }
};
struct SegTree {
    int n;
    vector<Mat> tree;
    void init(int _n) {
        n = _n;
        tree.assign(2 * n, Mat::identity());
    }
    void build() {
        for (int i = n - 1; i > 0; --i) {
            tree[i] = tree[i << 1] * tree[i << 1 | 1];
        }
    }
    inline void update(int p, const Mat& val) {
        for (tree[p += n] = val; p >>= 1; ) {
            tree[p] = tree[p << 1] * tree[p << 1 | 1];
        }
    }
    inline Mat query(int l, int r) {
        if (l > r) return Mat::identity();
        Mat resL = Mat::identity(), resR = Mat::identity();
        for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
            if (l & 1) resL = resL * tree[l++];
            if (r & 1) resR = tree[--r] * resR;
        }
        return resL * resR;
    }
};
long long pow2[200005];
void solve() {
    int N;
    long long K;
    if (!(cin >> N >> K)) return;
    vector<int> A(N - 1);
    for (int i = 0; i < N - 1; i++) cin >> A[i];
    int V = 2 * N - 1;
    vector<int> L(V, -1), R(V, -1), parent(V, -1);
    BIT bit(N);
    vector<int> pos_to_node(N + 1);
    for (int i = 1; i <= N; i++) {
        bit.add(i, 1);
        pos_to_node[i] = i - 1;
    }
    for (int i = 0; i < N - 1; i++) {
        int p1 = bit.find_kth(A[i]);
        int p2 = bit.find_kth(A[i] + 1);
        int u = pos_to_node[p1];
        int v = pos_to_node[p2];
        int new_node = N + i;
        L[new_node] = u; R[new_node] = v;
        parent[u] = new_node; parent[v] = new_node;
        pos_to_node[p1] = new_node;
        bit.add(p2, -1);
    }
    int root = 2 * N - 2;
    vector<int> sz(V, 0), heavy(V, -1);
    auto dfs_sz = [&](auto& self, int u) -> void {
        if (u < N) {
            sz[u] = 1;
            return;
        }
        self(self, L[u]); self(self, R[u]);
        sz[u] = sz[L[u]] + sz[R[u]];
        if (sz[L[u]] >= sz[R[u]]) heavy[u] = L[u];
        else heavy[u] = R[u];
    };
    dfs_sz(dfs_sz, root);
    vector<int> head(V, -1), in(V, -1), tail(V, -1);
    int timer = 0;
    auto dfs_hld = [&](auto& self, int u, int h) -> void {
        head[u] = h;
        in[u] = timer++;
        if (heavy[u] != -1) {
            self(self, heavy[u], h);
            tail[u] = tail[heavy[u]];
        } else {
            tail[u] = u;
        }
        if (L[u] != -1 && L[u] != heavy[u]) self(self, L[u], L[u]);
        if (R[u] != -1 && R[u] != heavy[u]) self(self, R[u], R[u]);
    };
    dfs_hld(dfs_hld, root, root);
    SegTree initial_seg;
    initial_seg.init(V);
    vector<Vec> initial_leaf_vec(V);
    for (int i = 0; i < N; i++) {
        initial_leaf_vec[i] = Vec(pow2[sz[i] - 1], pow2[sz[i] - 1], pow2[sz[i] - 1]);
    }
    for (int u = N; u < V; u++) {
        int light = (L[u] == heavy[u]) ? R[u] : L[u];
        Vec light_val = Vec(pow2[sz[light] - 1], pow2[sz[light] - 1], pow2[sz[light] - 1]);
        initial_seg.tree[initial_seg.n + in[u]] = make_matrix(light_val);
    }
    initial_seg.build();
    SegTree seg;
    vector<Vec> leaf_vec;
    auto get_path_W = [&](int h) -> Vec {
        int bottom = tail[h];
        Mat m = seg.query(in[h], in[bottom] - 1);
        return m * leaf_vec[bottom];
    };
    auto update_leaf = [&](int leaf_idx, Vec new_W) {
        leaf_vec[leaf_idx] = new_W;
        int curr = leaf_idx;
        while (curr != -1) {
            int h = head[curr];
            Vec top_W = get_path_W(h);
            int p = parent[h];
            if (p != -1) {
                seg.update(in[p], make_matrix(top_W));
            }
            curr = p;
        }
    };
    for (int target : {0, 1, 2}) {
        seg = initial_seg;
        leaf_vec = initial_leaf_vec;
        long long K_rem = K;
        string ans = "";
        ans.reserve(N);
        bool possible = true;
        for (int i = 0; i < N; i++) {
            bool found = false;
            for (int c : {1, 0, 2}) {
                Vec v(0, 0, 0);
                v.v[c] = 1;
                update_leaf(i, v);
                long long ways = get_path_W(head[root]).v[target];
                if (K_rem <= ways) {
                    ans += (c == 0 ? 'R' : (c == 1 ? 'P' : 'S'));
                    found = true;
                    break;
                } else {
                    K_rem -= ways;
                }
            }
            if (!found) {
                possible = false;
                break;
            }
        }
        if (possible) cout << ans << "\n";
        else cout << "-1\n";
    }
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    pow2[0] = 1;
    for (int i = 1; i <= 200000; i++) pow2[i] = min(INF, pow2[i - 1] * 2LL);
    int T;
    if (cin >> T) {
        while (T--) solve();
    }
    return 0;
}
0