Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

O(n) 解法,关键在于判环与映射。

Posted by ShenNaizhi at 2025-08-03 22:31:17 on Problem 1026
Key 是单射,所以规则对应了若干个环(如 key 为 {3, 2, 1} 时候(1-base),对于下标 1 的元素来说,第 1 次移动到下标 3,第 2 次移动到下标 1,故这个环长度为 2;相对地,下标 2 的元素所在的环是一个长度为 1 的自环)。找出这些环,并规定好原下标对应的位置(映射),即可在生成答案串时,对于某一 idx ,通过 (映射位置 + 环长) % k 得到最终位置,具体操作可参考如下代码:
```core code (cpp)
struct rule {
    rule(int size) : size(size), id(size), offset(size) {}
    std::vector<std::vector<int> > loops;
    std::vector<int> id; // id[i]: the i-th elem is in id[i]-th loop
    std::vector<int> offset; // offset[i]: the i-th elem is at offset[i] in loop
    int size;
};

rule get_rule(std::vector<int>& key) {
    const int N = key.size();
    std::vector<bool> vis(N);
    rule res(N);
    for (int i = 0; i < N; i++) {
        if (vis[i]) continue;
        std::vector<int> loop;
        for (int p = i; !vis[p]; p = key[p]) {
            vis[p] = true;
            loop.push_back(p);
        }
        for (int j = 0; j < loop.size(); j++) {
            res.id[loop[j]] = res.loops.size();
            res.offset[loop[j]] = j;
        }
        // res.loops.emplace_back(loop);
        res.loops.push_back(loop);
    }
    return res;
}

std::string encode(const rule& R, int k, std::string& s) {
    while (s.length() < R.size) s += ' ';
    std::string res(R.size, ' ');
    for (int i = 0; i < R.size; i++) {
        const std::vector<int>& loop = R.loops[R.id[i]];
        res[loop[(R.offset[i] + k) % loop.size()]] = s[i];
    }
    return res;
}

void solve(const rule& R) {
    int k;
    std::string s;
    while (true) {
        std::cin >> k;
        if (k == 0) return;
        std::cin.get();
        std::getline(std::cin, s);
        std::cout << encode(R, k, s) << "\n";
    }
}

int main() {
    for (int n; ; ) {
        std::cin >> n;
        if (n == 0) break;
        std::vector<int> key(n);
        for (int i = 0; i < n; i++) {
            std::cin >> key[i];
            key[i]--;
        }
        rule r = get_rule(key);
        solve(r);
        std::cout << "\n";
    }
    return 0;
}
```

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator