约瑟夫问题

解法

基础递推式 f[0] = 1;
f[i] = (f[i-1] + m) % i; 输出时f[n]要加上1,因为推导过程是n个人在从0开始编号的情况下。

证明

略.....

#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <cstring>
#include <algorithm>
#define rint register int
#define ll long long
#define lson x<<1
#define rson x<<1|1
#define mid ((st[x].l + st[x].r) >> 1)
using namespace std;
template <typename xxx> inline void read(xxx &x)
{
    int f = 1;x = 0;
    char c = getchar();
    for(; c < '0' || c > '9' ; c = getchar()) if(c=='-') f = -1;
    for(;'0' <= c && c <= '9'; c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    x *= f;
}
template <typename xxx> inline void print(xxx x)
{
    if(x < 0) {
        putchar('-');
        x = -x;
    }
    if(x > 9) print(x/10);
    putchar(x % 10 + '0');
}
const int inf = 0x7fffffff;
const int maxn = 1000100;
const int mod = 10007;
ll n,m;
ll pre,now;
int main()
{
    int t;read(t);
    while(t--) {
        read(n);read(m);
        now = 0;
        for(register ll i = 2;i <= n; ++i) {
            if(now + m < i){
                ll x = (i - now) / m;
                if(i + x < n) {
                    i += x;
                    now = (now + x * m);
                }
                else {
                    now = now + (n - i) * m;
                    i = n;
                }
            }
            now = (now + m)%i;
        }       
        print(now + 1);putchar('
');
    }
}
/*
56行存在的意义:第i层刚开始时,now为第i-1层时的值,进入if后i加上x为i+x,now加上x个m值更新到了第i+x-1层,但每层的任务是更新该层的值,没有本行
i进入下一层循环变成i+x+1,则第i+x层并没有更新
45行不能写等于 
*/
原文地址:https://www.cnblogs.com/Thomastine/p/11861057.html