Josephus Problem II
Key Idea: Binary search over a segment tree of alive positions to jump straight to the k-th surviving person after each elimination.
Solution
#include <bits/stdc++.h>
using namespace std;
//author: von_Braun
#define ll long long
#define lli long long int
#define pb push_back
#define rep(var, start, num) for(ulli var = start; var <start + num; var++)
#define all(x) x.begin(), x.end()
#define ulli unsigned long long int
#define ull unsigned long long
bool sortbysec(const pair<ll,ll> &a,const pair<ll,ll> &b) { return (a.second < b.second); }
void update_pref(int ti, int tl, int tr, vector<int> &tree, vector<int> &arr, int mi) {
if (tl==tr && tl==mi) {tree[ti]=arr[mi]; return;}
int m = (tl+tr)/2;
if (mi <= m) {update_pref(2*ti + 1, tl, m, tree, arr, mi);} else {
update_pref(2*ti +2, m+1, tr, tree, arr, mi);
}
tree[ti] = tree[2*ti + 1] + tree[2*ti + 2];
return;
}
int get_prefix(int l, int num, int ti, int tl, int tr, vector<int> &tree) {
if (tl==l && tr==num) {return tree[ti];}
int m = (tl+tr)/2;
if (num <= m) {
return get_prefix(l, num, 2*ti + 1, tl, m, tree);
} else if (l > m){
return get_prefix(l, num, 2*ti + 2, m+1, tr, tree);
} else {
return (get_prefix(l, m, 2*ti + 1, tl, m, tree) + get_prefix(m+1, num, 2*ti+2, m+1, tr, tree));
}
}
int find_kth(int k, vector<int> &arr, vector<int> &tree) {
int n =arr.size() - 1;
int l = 1;
int r = n;
while(r!=l) {
int m = (l+r)/2;
int z = get_prefix(1, m, 0, 1, n, tree);
// cout<<"LR "<<l<<" "<<r<<" "<<m<<" "<<z<<" "<<k<<endl;
if (z>=k) {
r=m;
} else {
l=m+1;
}
if (r-l <= 1) {break;}
}
if (get_prefix(1, l, 0, 1, n, tree) == k) {return l;} else if(get_prefix(1, r, 0, 1, n, tree) == k) {
return r;
} else {
cout<<"BRUH2\n"; return -1;
}
}
void solve() {
int n,k;
cin>>n>>k;
set<int> S;
rep(i,1,n) {S.insert(i);}
int curval=1;
vector<int> arr(n+1,1);
vector<int> tree(4*n + 4,0);
rep(i,1,n) {
update_pref(0, 1, n, tree, arr, i);
}
while(!S.empty()) {
int curidx = get_prefix(1,curval, 0, 1, n, tree);
int newidx = 1 + (curidx - 1 + k)%(S.size());
int newval = find_kth(newidx, arr ,tree);
auto f = S.find(newval);
if (f!=S.end()) {S.erase(f);} else {cout<<"WHAT\n";}
arr[newval]=0;
cout<<newval<<" ";
update_pref(0,1,n,tree,arr,newval);
if (S.size()==0) {break;}
auto it = S.lower_bound(newval);
if (it==S.end()) {it=S.begin();}
curval = *it;
}
}
int main() {
//add quotes incase input output file
//freopen(input.txt,r,stdin);
//freopen(output.txt,w,stdout);
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int tc = 1;
// cin >> tc;
for (int t = 1; t <= tc; t++) {
solve();
}
}