Problemas de juego / juegos giratorios
Enlace del título: luogu P1965
Idea general
Hay un círculo donde la gente gira en el sentido de las agujas del reloj según el número, y cada vez que la gente se mueve.
El método de movimiento consiste en que cada persona camine m pasos en el sentido de las agujas del reloj (se indica m).
Pregunte dónde está ahora la persona que estaba originalmente en la posición x después de tomar la décima potencia de k.
Múltiples grupos de consultas.
Ideas
Obviamente, la respuesta es esta: (x + 1 0 k × m) mod n (x + 10 ^ k \ times m) \ mod n( x+1 0k×m )m o dnorte
Primero me quedé sin la sección de bucle, y luego determiné a dónde fui a la sección de bucle al final, y la emití.
Debido a que hay poderes, podemos usar poderes rápidos para acelerarlo.
Código
#include<cstdio>
#define ll long long
using namespace std;
ll n, m, k, x;
ll q[1000001], zq;
ll read() {
ll re = 0, zf = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') zf = -zf;
c = getchar();
}
while (c >= '0' && c <= '9') {
re = (re << 3) + (re << 1) + c - '0';
c = getchar();
}
return re * zf;
}
void write(ll now) {
if (now < 0) {
printf("-");
write(-now);
return ;
}
if (now > 9ll) write(now / 10);
putchar(now % 10 + '0');
}
ll ksm(ll X, ll y) {
//快速幂
ll re = 1ll;
while (y) {
if (y & 1) re = (re * X) % zq;
X = (X * X) % zq;
y >>= 1;
}
return re % zq;
}
int main() {
// freopen("game.in", "r", stdin);
// freopen("game.out", "w", stdout);
n = read();
m = read();
k = read();
x = read();
int now = x;
q[zq++] = now;
while ((now + m) % n != x) {
now = (now + m) % n;
q[zq++] = now;
}
k = ksm(10ll, k);
write(q[k]);
fclose(stdin);
fclose(stdout);
return 0;
}