“五四”青年节到了,某学校要举行一个游园活动,其中有一个这样的游戏: n 个同学(编号从 0 到 n-1)围坐一圈,按照顺时针方向给 n 个位置编号,从0 到 n-1。最初,第 0 号同学在第 0 号位置,第 1 号同学在第 1 号位置,„„,
依此类推。
游戏规则如下:每一轮第 0 号位置上的同学顺时针走到第 m 号位置,第 1号位置同学走到第 m+1 号位置,„„,依此类推,第 n − m 号位置上的同学走到第 0 号位置,第 n-m+1 号位置上的同学走到第 1 号位置,„„,第 n-1 号位置上的同学顺时针走到第 m-1 号位置。
现在,一共进行了 10^k 轮,请问 x 号同学最后走到了第几号位置。
1< n<1,100,000;0< m< n;1< =x<=n;0< k<10^9
用快速幂一边求一边mod n
(ksm)快速幂为一个快速求幂的算法
很容易想到,其实比如说算2^4的时候当算到2^2时只要平方一下就好了,不用再算2^3的值是多少。下面的快速幂的方法就要用到这一点,利用二进制的方法减小复杂度。
用临时变量tmp记录现在算到的幂(即上文说到2^2)大体思路是这样的,我们只在二进制位为1的位做一次,返回值变量(ret)乘以tmp。
时间复杂度(log k)
var
n,m,k,x:longint;
function ksm(a,b:longint):longint;//a的b次幂
var
x,y:int64;
begin
x:=1;//最终值
y:=a;//底数
while b>0 do
begin
if (b and 1)=1 then x:=x*y mod n;
//当二进制末尾为1时更新x
y:=y*y mod n;
b:=b shr 1;//相当于b=b div 2
end;
exit(x);
end;
begin
readln(n,m,k,x);
writeln(((ksm(10,k)*m mod n)+x) mod n);
end.
#include
using namespace std;
long long n,m,k,x;
long long ksm(long long a,long long b)
{
long long x,y;
x=1;
y=a;
while (b>0)
{
if ((b&1)==1) x=(x*y)%n;
y=(y*y)%n;
b=b>>1;
}
return(x);
}
int main()
{
scanf("%lld%lld%lld%lld",&n,&m,&k,&x);
printf("%lld",(((ksm(10,k)*m)%n)+x)%n);
}