有3种方法
Solution 1 - ordered_set
Utilizing the ordered_set
This data structure is an extension of the general set
in C++.
It allows searching for the K-th smallest element in O(log n) time complexity.
#include <iostream>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
int main()
{ int n, k;cin >> n >> k;ordered_set os;for (int i = 1; i <= n; i++){os.insert(i);}int cur = 0;for (int i = 1; i <= n; i++){cur = (cur + k) % os.size();auto it = os.find_by_order(cur);cout << *it << " ";os.erase(it);}return 0;
}
Solution 2 Blocking Simulation
Assume N is the size of the list, we can divide the numbers into K × K K\times K K×K matrix, where K = N K=\sqrt{N } K=N…
这样模拟的时候,做N次循环,循环内枚举为 s q r t N sqrt{N} sqrtN的常数倍,其中模拟复杂度为 O ( N N ) O(N\sqrt{N}) O(NN)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pii;
void solve()
{int n, k;cin >> n >> k;int m = sqrt(n);vector<vector<int>> g;for (int i = 1; i <= n;){vector<int> tmp;while (tmp.size() < m && i <= n){tmp.push_back(i++);}g.push_back(tmp);}int x = 0, y = 0;for (int i = 0; i < n; i++){int j = k % (n - i);while (j){if (y + j < g[x].size()){y += j;j = 0;}else{j -= g[x].size() - y;y = 0;x = (x + 1) % g.size();}}// 矫正错误位置while (y >= g[x].size()){y = 0;x = (x + 1) % g.size();}cout << g[x][y] << " ";// 最后一个不用删除 避免死循环if (i < n - 1){g[x].erase(g[x].begin() + y);while (y >= g[x].size()){y = 0;x = (x + 1) % g.size();}}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);int t;t = 1;while (t--){solve();}
}
Solution 3 Segment tree
We can generalize this problem into easy range query problem …
Subsequent content will be here soon…,