※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 23893번 문제인 알프스의 힘이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/23893
23893번: 알프스의 힘
첫 번째 줄에 $N, P, K$가 주어진다. 두 번째 줄에는 수열 $A_1, A_2, … , A_N$이 주어진다.
www.acmicpc.net
편의상 Ai = a, Aj = b라고 표기하자. 문제 조건에 따라 i와 j가 다르다면 a와 b는 항상 서로 다르다.
a와 b가 서로 다르다는 전제 하에서, a^2 + ab + b^2와 k가 합동이라는 것은 (a-b)(a^2 + ab + b^2)와 k(a-b)가 합동이라는 것과 동치관계이다. (a-b의 multiplicative modular inverse가 항상 존재하기 때문이다.)
저 식을 정리하면, 이 문제는 a^3 - ka 와 b^3 - kb 가 서로 합동인 a와 b를 찾는 문제라는 것을 알아낼 수 있다.
오버플로우에 유의하여 위의 관계식을 만족하는 a와 b의 쌍을 잘 구해보자.
입력 순서와 관련있는 i와 j의 순서(i<j 조건)는 크게 신경쓸 필요가 없다. (a,b)와 (b,a)의 두 페어 중 한 가지만을 세기만 하면 같은 값을 구할 수 있기 때문이다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll arr[100000];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
ll N, P, K; cin >> N >> P >> K;
for (int i = 0; i < N; i++) {
ll x; cin >> x;
arr[i] = (((x * x) % P) * x - K * x) % P;
if (arr[i] < 0) arr[i] += P;
}
sort(arr, arr + N);
ll ans = 0;
ll old = -1, cnt = 0;
for (int i = 0; i < N; i++) {
if (arr[i] == old) cnt++;
else {
ans += cnt * (cnt - 1) / 2;
old = arr[i];
cnt = 1;
}
}
ans += cnt * (cnt - 1) / 2;
cout << ans;
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 7677 // C++] Fibonacci (0) | 2022.01.24 |
---|---|
[BOJ 7490 // C++] 0 만들기 (0) | 2022.01.23 |
[BOJ 1407 // C++] 2로 몇 번 나누어질까 (0) | 2022.01.21 |
[BOJ 17509 // C++] And the Winner Is... Ourselves! (0) | 2022.01.20 |
[BOJ 17370 // C++] 육각형 우리 속의 개미 (0) | 2022.01.19 |