知識點 - 約瑟夫環(公式總結)

知識點 - 約瑟夫環(公式總結)

一、nn個人,1至m報數,問最後剩下來的人的編號

公式

f(n,m)=(f(n1,m)+m)%nf(n,m) = (f(n-1,m)+m)\%n

f(0,m)=0f(0,m) = 0

複雜度 O(n)O(n)

代碼

typedef long long ll;
ll calc(int n, ll m) {
	ll p = 0;
	for (int i = 2; i <= n; i++) {
		p = (p + m) % i;
	}
	return p + 1;//
}

二、nn個人,11mm報數,問第kk個出局的人的編號 (k<106k < 10^6)

公式

f(n,k)=(f(n1,k1)+m1)%n+1f(n,k) = (f(n-1,k-1)+m-1)\%n + 1

f(nk+1,1)=m%(nk+1)f(n-k+1,1) = m\%(n-k+1) if(f==0)f=nk+1if (f == 0) f = n - k + 1

複雜度 O(k)O(k)

代碼

typedef long long ll;
ll calc(int n, ll m) {
	ll p = 0;
	for (int i = 2; i <= n; i++) {
		p = (p + m) % i;
	}
	return p + 1;//
}

三、nn個人,11mm報數,問第kk個出局的人的編號(m<106m < 10^6

公式:同上,這裏的核心是一下子跳多次,不是一個一個轉移

複雜度: O(mlog(m))O(m*log(m))

代碼

ll cal2(ll n, ll m, ll k) {
	if (m == 1) return k;
	else {
		ll a = n - k + 1, b = 1;
		ll c = m % a, x = 0;
		if (c == 0) c = a;
		while (b + x <= k) {
			a += x, b += x, c += m * x;
			c %= a;
			if (c == 0) c = a;
			x = (a - c) / (m - 1) + 1;
		}
		c += (k - b) * m;
		c %= n;
		if (c == 0) c = n;
		return c;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章