Josephus 线段数版

每次计算出当前点与第一个点的距离即可。

代码如下;

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<iostream>

#include<vector>

#include<string>

#include<math.h>

#include<map>

#include<set>

#include<algorithm>

#define MAXN 100000



using namespace std;



int N, M, cur;



struct node

{

    int l, r;

    int sum; //g

    int v;

}s[MAXN<<2];



void push_up(int p) {

    s[p].sum = s[p<<1].sum + s[p<<1|1].sum;    

}



void build(int p, int l, int r) {

    s[p].l = l, s[p].r = r;  

    if (l != r) {

        int mid = (l + r) >> 1;

        build(p<<1, l, mid);

        build(p<<1|1, mid+1, r);

        push_up(p);

    } else {

        s[p].sum = 1;

        s[p].v = l;

    }

}int query(int p, int x) {

    if (s[p].l == s[p].r) {

        s[p].sum = 0;

        return s[p].v;   

    }

    int k;

    if (x > s[p<<1].sum) {

        k = query(p<<1|1, x-s[p<<1].sum);

        push_up(p);

        return k;

    } else {

        k = query(p<<1, x);

        push_up(p);

        return k;

    }

}



int main( )

{

    while (scanf("%d %d", &N, &M) == 2) {

        cur = 1;

        build(1, 1, N);

        while (s[1].sum > 0) {

            cur += M-1; 

            if (cur >= s[1].sum) {

                cur %= s[1].sum;

                if (!cur) cur = s[1].sum;

            }

            printf("%d ", query(1, cur)); 

        }

        puts("");

    }

    return 0;

}

你可能感兴趣的:(OS)