# 2020牛客多校六 J. Josephus Transform （线段树求约瑟夫变换+置换群的幂）

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
const int MAXN = 1e5 + 5;
int sum[MAXN << 2];
struct Node {
int l, r;
int mid() { return (l + r) >> 1; }
} tree[MAXN << 2];
void build(int l, int r, int rt) {
tree[rt].l = l;
tree[rt].r = r;
if (l == r) {
sum[rt] = 1;
return;
}
int m = tree[rt].mid();
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
int query(int rt, int pos) {
sum[rt]--;
if (tree[rt].l == tree[rt].r) return tree[rt].l;
if (sum[rt << 1] >= pos) return query(rt << 1, pos);
else return query(rt << 1 | 1, pos - sum[rt << 1]);
}
int p[MAXN], temp[MAXN], ans[MAXN], n;
bool vis[MAXN];
void solve(int t) {   //O(n)实现置换群p的t次幂
memset(vis, false, n + 5);
for (int i = 1; i <= n; i++) {
if (vis[i])
continue;
vector<int> circle;
int pos = i;
while (!vis[pos]) {
circle.push_back(pos);
vis[pos] = true;
pos = p[pos];
}
int sz = circle.size();
for (int i = 0; i < sz; i++)
temp[circle[i]] = ans[circle[(i + t) % sz]];
}
for (int i = 1; i <= n; i++) ans[i] = temp[i];
}
int m, k, x;
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) ans[i] = i;
while (m--) {
build(1, n, 1);
scanf("%d%d", &k, &x);
int pos = 1, cnt = n;
for (int i = 1; i <= n; i++) {
pos = (pos - 1 + k - 1) % cnt + 1;   //取出元素在剩余序列的位置
p[i] = query(1, pos);
//cout << p[i] << endl;
cnt--;
}
solve(x);
}
for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
return 0;
}

07-15 224

08-08 696
08-01 55