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;
}
posted @ 2012-09-20 21:22  沐阳  阅读(254)  评论(0编辑  收藏  举报