Last week I participated in round 1b of the Facebook Hacker cup.
One of the problems was basically the Josephus problem
I've studied the Josephus problem before as a discrete math problem, so I basically understand how to get the recurrence:
f(n,k) = (f(n-1,k) + k) mod n, with f(1,k) = 0
But that didn't work in the Facebook Hacker Cup, because the max value of n was 10^12. The mak value of k was 10^4.
Wikipedia mentions an approach when k is small and n is large. Basically remove people from a single round, and then renumber. But it's not described much and I don't understand why the renumbering works.
I looked at sample working source code for the solution, but I still don't understand that final portion.
long long joseph (long long n,long long k) {
if (n==1LL) return 0LL;
if (k==1LL) return n-1LL;
if (k>n) return (joseph(n-1LL,k)+k)%n;
long long cnt=n/k;
long long res=joseph(n-cnt,k);
res-=n%k;
if (res<0LL) res+=n;
else res+=res/(k-1LL);
return res;
}
The part I really don't understand is starting from res-=n%k
(and the lines thereafter). How do you derive that that is the way to adjust the result?
Could someone show the reasoning behind how this is derived? Or a link that derives it? (I didn't find any info on UVA or topcoder forums)