15710번: xor 게임
첫째 줄에 정수 a, b (0 ≤ a, b < 231), n(0 < n ≤ 109)이 공백으로 구분되어 주어진다.
www.acmicpc.net
xor 연산에 대해 잘 모르면 해결하기 어려운 문제입니다.
먼저 몇 가지 예시를 통해 생각해봅시다.
예를 들어, 10111011(2) 과 xor연산을 해서 00000111(2) 이 되는 수가 있을까요?
네, 10111100(2) 이 바로 그런 숫자입니다.
그러면 10111011(2) 과 xor연산을 해서 11100111(2)이 되는 수는 있을까요?
네, 01011100(2) 이 바로 그런 숫자입니다.
비단 10111011(2) 뿐만이 그런게 아니라, 일반적으로 모든 a,b 에 대해 a xor x = b의 근 x가 항상 존재하고, 이 근은 유일합니다.
따라서 게임의 N−1번째 턴의 결과로 chogahui05가 가진 카드에 적힌 숫자가 X라고 한다면,
chogahui05는 N번째 턴에서 반드시 X와 xor연산하여 b가 나오는 값을 선택할 수 있습니다. (X와 b의 값에 상관없이!)
즉 게임의 과정에서 N번째 턴의 결과가 b가 되기 위해 고를 수 있는 카드는 반드시 한 개 존재하며
그 외의 턴에서 고를 수 있는 카드는 231개가 됩니다.
따라서 N이 주어졌을 때 (231)N−1=2147483648N−1 을 (109+7)로 나눈 나머지를 구해주면 해결되는 문제입니다.
코드는 다음과 같습니다.
#include <stdio.h>
#define mod 1000000007
long long power_modular (long long base, int power);
int main() {
int a, b, n;
scanf("%d %d %d", &a, &b, &n);
printf("%lld", power_modular(2147483648ll, n-1));
return 0;
}
long long power_modular (long long base, int power) {
base %= mod;
long long result = 1;
while(power) {
if (power % 2) {
result = (result * base) % mod;
}
base = (base * base) % mod;
power /= 2;
}
return result;
}
(C11, 1116KB, 0ms, 제출번호 26406084)
2147483648N−1 을 231×(N−1) 으로 해석하여 구할 수도 있습니다.
다만 그 경우엔 power에 들어갈 값이 int범위를 초과할 수 있어 long long으로 바꿔주어야합니다.
글쓰고 있는 시점에서 적용중인 코드 하이라이팅 스크립트에서 2147483648에 postfix로 붙인 LL을 감지 못하고 있습니다만,
2147483648이 long long임을 나타내기 위해 postfix로 LL을 붙여주었습니다.
modulo가 소수이고 N≤109+7이므로 base자리에 2를 넣고 페르마의 소정리를 써서
power자리에 31×(N−1)을 (109+6)으로 나눈 값을 넣어도 될 것 같습니다.
'분할 정복을 이용한 거듭제곱 > 정수 거듭제곱' 카테고리의 다른 글
백준 1492번: 합 (0) | 2021.02.19 |
---|---|
백준 15824번: 너 봄에는 캡사이신이 맛있단다 (0) | 2021.02.19 |
백준 15717번: 떡파이어 (0) | 2021.02.18 |
백준 18291번: 비요뜨의 징검다리 건너기 (0) | 2021.02.18 |
백준 14731번: 謎紛芥索紀 (Large) (0) | 2021.02.18 |