约瑟夫环——树状数组

约瑟夫环——树状数组

  • 树状数组维护当前队中剩余元素和
    • 每次二分查找前缀和为(now +(k-1))% (剩余人数) 的元素

树状数组维护当前队中剩余元素和

每次二分查找前缀和为(now +(k-1))% (剩余人数) 的元素

去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m,tr[1000002],l,r,mid,now,outt;

void add(int x, int val)
{
	while (x<=n){
		tr[x] += val;
		x += (x&-x);
	}
}

int get_sum(int x)
{
	int re = 0;
	while (x){
		re += tr[x];
		x -= (x&-x);
	}
	return re;
}

int findd(int x)
{
	l = 1, r = n;
	while (l < r){
		mid = (l + r) >> 1;
		if (get_sum(mid) >= x) r = mid;
		else l = mid + 1;
	}
	return l;
}

int main()
{
	freopen("aa.out","w",stdout);
	scanf("%d %d", &n, &m);
	if (!n) return 0;
	for (int i=1; i<=n; i++) add(i, 1);
	now = 1;
	for (int i=1; i<=n; i++){
		now = ( now + (m-1) ) % (n-i+1);
		if (!now) now = (n-i+1);
		outt = findd(now);
		printf("%d ", outt);
		add(outt, -1);
	}
}

注意: 模运算会出现为 0 的情况, 要特判
或 (x-1 % mo)+ 1, 改变模运算值域


你可能感兴趣的:(约瑟夫环——树状数组)