結果
| 問題 |
No.1013 〇マス進む
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-03-20 23:57:22 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 5,460 bytes |
| コンパイル時間 | 2,133 ms |
| コンパイル使用メモリ | 183,784 KB |
| 実行使用メモリ | 20,180 KB |
| 最終ジャッジ日時 | 2024-12-15 21:30:22 |
| 合計ジャッジ時間 | 15,700 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 RE * 2 |
| other | AC * 2 RE * 60 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAX_V = 100000;
int V;
vector<int> G[MAX_V];
vector<int> rG[MAX_V];
vector<int> vs;
bool used[MAX_V];
int cmp[MAX_V];
void add_edge(int from, int to) {
G[from].push_back(to);
rG[to].push_back(from);
}
void dfs(int v) {
used[v] = true;
for (int i = 0; i < G[v].size(); i++) {
if (!used[G[v][i]]) dfs(G[v][i]);
}
vs.push_back(v);
}
void rdfs(int v, int k) {
used[v] = true;
cmp[v] = k;
for (int i = 0; i < rG[v].size(); i++) {
if (!used[rG[v][i]]) rdfs(rG[v][i], k);
}
}
int scc() {
memset(used, 0, sizeof(used));
vs.clear();
for (int v = 0; v < V; v++) {
if (!used[v]) dfs(v);
}
memset(used, 0, sizeof(used));
int k = 0;
for (int i = (int)vs.size() - 1; i >= 0; i--) {
if (!used[vs[i]]) rdfs(vs[i], k++);
}
return k;
}
void dfs_end(int cur, ll rest, const vector< vector<int> >& g, int n, const vector<int>& p, vector<ll>& ans, vector<int>& path) {
path.push_back(cur);
if (rest == 0) return;
for (int prv : g[cur]) {
if (rest > 0) ans[prv] = ans[cur] - n + prv + 1;
else ans[prv] = ans[cur] - path[-rest] - 1 + prv + 1;
dfs_end(prv, rest - 1, g, n, p, ans, path);
}
path.pop_back();
}
void dfs_loop(int cur, ll rest, const vector< vector<int> >& g, const int n, const vector<int>& p, vector<ll>& ans, vector<ll>& memo, vector<int>& loop_src, vector<int>& path) {
if (cur < n) {
memo[cur] = rest;
path.push_back(cur);
}
if (rest == 0) return;
for (int prv : g[cur]) {
if (rest > 0) ans[prv] = (cur == n ? 0 : ans[cur]) + prv + 1;
else ans[prv] = ans[cur] - path[-rest] - 1 + prv + 1;
if (cur < n) loop_src[prv] = loop_src[cur];
dfs_loop(prv, rest - 1, g, n, p, ans, memo, loop_src, path);
}
if (cur < n) path.pop_back();
}
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int n;
ll K;
cin >> n >> K;
vector<int> p(n);
for (int i = 0; i < n; ++i) {
cin >> p[i];
--p[i];
}
V = n;
for (int i = 0; i < n; ++i) {
if (p[i] + 1 == n) {
continue;
}
add_edge(p[i], p[(i + p[i] + 1) % n]);
}
int sz = scc();
vector<int> cnt(sz, 0);
for (int i = 0; i < n; ++i) {
++cnt[cmp[i]];
}
map<int, int> loop_comp_ids;
for (int i = 0; i < sz; ++i) {
if (cnt[i] > 1) {
int hoge = loop_comp_ids.size();
loop_comp_ids[i] = hoge;
}
}
vector< vector<int> > g(n + loop_comp_ids.size());
for (int i = 0; i < n; ++i) {
int to;
if (loop_comp_ids.find(cmp[i]) == loop_comp_ids.end()) {
to = i;
} else {
to = n + loop_comp_ids[cmp[i]];
}
for (int j : G[i]) {
if (cmp[i] == cmp[j]) continue;
int from;
if (loop_comp_ids.find(cmp[j]) == loop_comp_ids.end()) {
from = j;
} else {
from = n + loop_comp_ids[cmp[j]];
}
g[from].push_back(to);
}
}
vector<ll> ans(n, -1);
ans[n - 1] = n * K;
vector<int> path;
dfs_end(n - 1, K, g, n, p, ans, path);
/*
vector<ll> memo(n, -1);
for (auto& foo : loop_comp_ids) {
int loop_cmp = foo.first;
vector<int> loops;
vector<int> dict_loops(n, -1);
vector<int> loop_src(n, -1);
for (int i = 0; i < n; ++i) {
if (cmp[i] == loop_cmp) {
loop_src[i] = i;
memo[i] = K;
ans[i] = 0;
if (loops.empty()) {
int tar = i;
while (tar != -1) {
dict_loops[tar] = loops.size();
loops.push_back(tar);
for (int nex : G[tar]) {
if (nex == i) {
tar = -1;
break;
} else if (cmp[nex] == cmp[tar]) {
tar = nex;
break;
}
}
}
}
continue;
}
for (int j : G[i]) {
if (cmp[j] == loop_cmp) {
loop_src[i] = j;
break;
}
}
}
int loop_size = loops.size();
vector<ll> sum_loops(2 * loop_size + 1, 0);
for (int i = 0; i < loop_size; ++i) {
sum_loops[i + 1] = sum_loops[i] + loops[i] + 1;
}
for (int i = 0; i < loop_size; ++i) {
sum_loops[i + 1 + loop_size] = sum_loops[i + loop_size] + loops[i] + 1;
}
path.clear();
dfs_loop(n + foo.second, K, g, n, p, ans, memo, loop_src, path);
for (int i = 0; i < n; ++i) {
if (loop_src[i] == -1) continue;
ll hoge = memo[i] / loop_size * sum_loops[loop_size];
memo[i] %= loop_size;
hoge += sum_loops[dict_loops[loop_src[i]] + memo[i]] - sum_loops[dict_loops[loop_src[i]]];
ans[i] += hoge;
}
}*/
for (int i = 0; i < n; ++i) {
assert(ans[p[i]] != -1);
cout << ans[p[i]] + i + 1 << "\n";
}
return 0;
}