求n个人,每次报m次出队,求第k个出队的人
f[n][k]=(f[n−1][k−1]+m−1)%nf[n][k]=(f[n-1][k-1]+m-1)\%nf[n][k]=(f[n−1][k−1]+m−1)%n
时间复杂度为O(k)O(k)O(k)
当kkk很大但是m<<nm<<nm<<n时,可以把多次(m−1)(m-1)(m−1)加在一起,一起取模
#include <bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
long long n,m,k,i,s,mod,num;
int T,t,l;
int main()
{
scanf("%d",&T);
fo(t,1,T)
{
scanf("%lld%lld%lld",&n,&k,&m);
if (m == 1) {printf("Case #%d: %lld\n",t,k); continue;}
mod = n - k + 1;
s = m - 1; s = s % mod;
while (1)
{
num = (mod - s) / (m - 1);
num = min(num,n-mod);
s += num * m;
mod = mod + num;
s = s % mod;
if (mod == n) break;
s += m; mod++;
s = s % mod;
if (mod == n) break;
}
printf("Case #%d: %lld\n",t,s+1);
}
return 0;
}