约瑟夫环

#include <bits/stdc++.h>
using namespace std;
#define sc(x) scanf("%lld", &(x))
#define pr(x) printf("%lld\n", x)
#define first fi
#define second se
#define emplace_back eb
#define endl '\n'
#define rep(i, j, k) for (ll(i) = (j); (i) <= (k); (++i))
#define rrep(i, j, k) for (ll i = (ll)(j); i >= (ll)(k); i--)
#define mem(x, y) memset(x, y, sizeof(x))
typedef long double ld;
typedef long long ll;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
const ld pi = acos(-1);
const int mod = 1e9 + 7;
const ll INF = LLONG_MAX;
const int N = 1e5 + 7;
ll a[N];
//数据范围n<=10^18,m<=1000,时间几十ms
int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    ll f1 = 0;
    ll X;
    if (m == 1) {
        cout << n << endl;
        return 0;
    } else
        for (ll i = 2; i <= n; ++i) {
            if (f1 + m < i) {          //表示很有可能跳过X个i
                X = (i - f1) / m;      //能跳过多少个
                if (i + X < n) {       //如果没有跳过n,就是i<=N
                    i = i + X;         // i直接到i+X
                    f1 = (f1 + X * m); //由于f1+X*M肯定<=i,所以这里不用%i
                } else { //如果跳过了n,那么就不能直接加X了,而是只需要加(N-i)个M即可
                    f1 = f1 + (n - i) * m;
                    i = n;
                }
            }
            f1 = (f1 + m) % i;
            //如果f1+M>=i或者跳过上面的一些i之后还是要继续当前i对于的出列的人
        }
    cout << f1 + 1 << endl;
    return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务