結果
| 問題 | No.3510 RPS Eliminations |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-04-19 17:24:42 |
| 言語 | C++23 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 5,585 bytes |
| 記録 | |
| コンパイル時間 | 2,429 ms |
| コンパイル使用メモリ | 341,588 KB |
| 実行使用メモリ | 37,496 KB |
| 最終ジャッジ日時 | 2026-04-19 17:26:05 |
| 合計ジャッジ時間 | 16,241 ms |
|
ジャッジサーバーID (参考情報) |
judge3_1 / judge1_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 1 |
| other | AC * 20 TLE * 1 -- * 7 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
static const int WIN[3][3] = {
{-1, 1, 0},
{ 1,-1, 2},
{ 0, 2,-1},
};
static const int LEX[3] = {1, 0, 2};
const int MAXN = 200005;
const int MAXND = 400005;
struct Node {
uint64_t cnt[3];
int left, right, leaf_pos;
};
static Node nd[MAXND];
static int nc;
static int orig_node[MAXN];
static int leaf_nd[MAXN];
static int par[MAXND];
inline uint64_t sat_add(uint64_t a, uint64_t b, uint64_t cap){
return (a > cap - b) ? cap : a + b;
}
inline uint64_t sat_mul(uint64_t a, uint64_t b, uint64_t cap){
if (!a || !b) return 0;
return (a > cap / b) ? cap : min(cap, a * b);
}
int new_leaf(int pos){
int id = nc++;
nd[id] = {{1,1,1}, -1, -1, pos};
return id;
}
void compute_cnt(int id, uint64_t cap){
if (nd[id].left == -1){
nd[id].cnt[0] = nd[id].cnt[1] = nd[id].cnt[2] = 1;
return;
}
int l = nd[id].left, r = nd[id].right;
nd[id].cnt[0] = nd[id].cnt[1] = nd[id].cnt[2] = 0;
for (int a = 0; a < 3; a++){
if (!nd[l].cnt[a]) continue;
for (int b = 0; b < 3; b++){
if (a == b || !nd[r].cnt[b]) continue;
int w = WIN[a][b];
uint64_t v = sat_mul(nd[l].cnt[a], nd[r].cnt[b], cap);
nd[id].cnt[w] = sat_add(nd[id].cnt[w], v, cap);
}
}
}
static int bit[MAXN], bit_n;
void bit_upd(int i, int v){
for(; i <= bit_n; i += i & -i) bit[i] += v;
}
int bit_kth(int k){
int p = 0;
for(int pw = 1 << 17; pw; pw >>= 1)
if(p + pw <= bit_n && bit[p + pw] < k){
p += pw;
k -= bit[p];
}
return p + 1;
}
int build_tree(int N, int* A, uint64_t cap){
bit_n = N;
fill(bit + 1, bit + N + 1, 0);
for(int i = 1; i <= N; i++) bit_upd(i, 1);
nc = 0;
for(int i = 1; i <= N; i++) orig_node[i] = new_leaf(i);
for(int i = 0; i < N - 1; i++){
int ai = A[i];
int ol = bit_kth(ai), or_ = bit_kth(ai + 1);
int nl = orig_node[ol], nr = orig_node[or_];
int id = nc++;
nd[id] = {{0,0,0}, nl, nr, -1};
compute_cnt(id, cap);
bit_upd(or_, -1);
orig_node[ol] = id;
}
return orig_node[bit_kth(1)];
}
void build_par(int root){
fill(par, par + nc, -1);
stack<int> stk;
stk.push(root);
while(!stk.empty()){
int id = stk.top(); stk.pop();
if(nd[id].left != -1){
par[nd[id].left] = id;
par[nd[id].right] = id;
stk.push(nd[id].left);
stk.push(nd[id].right);
}
}
}
void find_leaves(int root){
stack<int> stk;
stk.push(root);
while(!stk.empty()){
int id = stk.top(); stk.pop();
if(nd[id].left == -1)
leaf_nd[nd[id].leaf_pos] = id;
else {
stk.push(nd[id].left);
stk.push(nd[id].right);
}
}
}
static uint64_t live[MAXND][3];
static int asgn[MAXN];
void recompute(int id, uint64_t cap){
if(nd[id].left == -1){
int p = nd[id].leaf_pos;
if(asgn[p] == -1){
live[id][0] = live[id][1] = live[id][2] = 1;
} else {
live[id][0] = live[id][1] = live[id][2] = 0;
live[id][asgn[p]] = 1;
}
return;
}
int l = nd[id].left, r = nd[id].right;
live[id][0] = live[id][1] = live[id][2] = 0;
for(int a = 0; a < 3; a++){
if(!live[l][a]) continue;
for(int b = 0; b < 3; b++){
if(a == b || !live[r][b]) continue;
int w = WIN[a][b];
uint64_t v = sat_mul(live[l][a], live[r][b], cap);
live[id][w] = sat_add(live[id][w], v, cap);
}
}
}
void init_live(int root, uint64_t cap){
vector<int> order;
stack<int> stk;
stk.push(root);
while(!stk.empty()){
int id = stk.top(); stk.pop();
order.push_back(id);
if(nd[id].left != -1){
stk.push(nd[id].left);
stk.push(nd[id].right);
}
}
for(int i = (int)order.size() - 1; i >= 0; i--)
recompute(order[i], cap);
}
void fix_pos(int pos, int game_c, uint64_t cap){
asgn[pos] = game_c;
int id = leaf_nd[pos];
while(id != -1){
recompute(id, cap);
id = par[id];
}
}
string find_kth(int root, int target, uint64_t K, int N, uint64_t cap){
fill(asgn + 1, asgn + N + 1, -1);
init_live(root, cap);
if(live[root][target] < K) return "-1";
string res(N, '?');
const char CH[3] = {'R','P','S'};
for(int pos = 1; pos <= N; pos++){
for(int li = 0; li < 3; li++){
int c = LEX[li];
fix_pos(pos, c, cap);
uint64_t cnt = live[root][target];
if(cnt >= K){
res[pos - 1] = CH[c];
break;
}
K -= cnt;
if(li == 2) return "-1";
}
}
return res;
}
static int A[MAXN];
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while(T--){
int N;
uint64_t K;
cin >> N >> K;
for(int i = 0; i < N - 1; i++)
cin >> A[i];
uint64_t cap = K;
int root = build_tree(N, A, cap);
build_par(root);
find_leaves(root);
for(int t = 0; t < 3; t++){
fill(asgn + 1, asgn + N + 1, -1);
init_live(root, cap);
if(live[root][t] < K){
cout << "-1\n";
} else {
cout << find_kth(root, t, K, N, cap) << "\n";
}
}
}
return 0;
}