Josephus Transform 加速置换
https://ac.nowcoder.com/acm/contest/5671/J
牛客多校j题,利用线段树nlogn写出模拟的操作快速幂
可以类似给转圈用
#include<iostream>
#include<set>
using namespace std;
typedef long long ll;
const int maxn = 2e5+11;
int list[maxn];
int vis[maxn];
int a[maxn];
set<int>ins;
set<int>::iterator it;
int n,m;
/*
cnt--;
p = (p%cnt + k - 1)%cnt;
*/
int tree[maxn*4];
int update(int node,int be,int en,int i,int val) {
int l = node*2;
int r = node*2+1;
int mid = be+en>>1;
if(be == en) {
tree[node] = val;
return 0;
}
if(i <= mid) update(l,be,mid,i,val);
else update(r,mid+1,en,i,val);
tree[node] = tree[l] + tree[r];
return 0;
}
int ans;
int qurry(int node,int be,int en,int sum) {
int l = node*2;
int r = node*2+1;
int mid = be+en>>1;
if(be == en) {
tree[node] --;
ans = be;
return 0;
}
if(sum <= tree[l]) {
qurry(l,be,mid,sum);
} else {
qurry(r,mid+1,en,sum - tree[l]);
}
tree[node] = tree[l] + tree[r];
return 0;
}
int cal(int *list,int *a) { //按照a的规则跑
for(int i=1; i<=n; i++) {
vis[i] = list[a[i]];
}
for(int i=1; i<=n; i++) {
list[i] = vis[i];
}
return 0;
}
int main() {
scanf("%d %d",&n,&m);
for(int i=1; i<=n; i++) {
list[i] = i;
update(1,1,n,i,1);
}
while(m--) {
int k,x;
scanf("%d %d",&k,&x);
int p = k-1;
int cnt = n;
for(int i=1; i<n; i++) {
qurry(1,1,n,p+1);
a[i] = ans;
cnt--;
p = (p%cnt + k - 1)%cnt;
}
qurry(1,1,n,p+1);
a[n] = ans;
for(int i=1;i<=n;i++){
update(1,1,n,i,1);
}
while(x){
if(x&1){
cal(list,a);
}
x>>=1;
cal(a,a);
}
}
for(int i=1; i<=n; i++) {
printf("%d ",list[i]);
}
printf("\n");
return 0;
}
寻找真正的热爱

浙公网安备 33010602011771号