모든 원소가 양의 정수이고, 길이가 인 수열 이 주어진다.
을 만족하는 모든 정수쌍 에 대해 의 합을 로 나눈 나머지를 구하시오.
첫째 줄에 수열 의 길이 이 주어진다.
둘째 줄에 수열 이 공백으로 구분되어 주어진다.
해당 문제를 처음 보고 가장 먼저 떠올릴 수 있는 방법은 두 개의 반복문을 이용해 모든 정수쌍을 탐색하는 것이다.
하지만 해당 문제의 제약 조건 중 으로 인해 의 시간복잡도를 가지는 로직으로는 시간 초과가 발생한다.
따라서 문제를 해결하기 위해서는 새로운 아이디어가 필요하다.
[5, 3, 6, 7]의 수열이 존재한다고 가정하겠다.
수열에서 모든 정수쌍을 구해서 더해보면 아래의 식과 같다.
(5 3) + (5 6) + (5 7) + (3 6) + (3 7) + (6 7)
위의 식에서 공통항을 빼내면 다음 식처럼 표현할 수 있다.
5 (3 + 6 + 7) + 3 (6 + 7) + (6 * 7)
해당 식을 통해 arr[i] * (arr의 총합 - arr[i])의 총합이라는 사실을 알 수 있다.
순차 탐색으로 수열의 총합을 구하는데 걸리는 시간복잡도는 이고, 전체 수열을 순회하며 수식의 연산을 진행하는 시간 또한 의 시간복잡도를 가진다.
따라서 위의 수식을 구현하면 의 시간복잡도만으로 문제를 해결할 수 있다.
import java.io.*; public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 수열의 개수 입력 int N = Integer.parseInt(br.readLine()); long sum = 0; long[] arr = new long[N]; // 수열 입력 및 수열의 총합 구하기 String[] s = br.readLine().split(" "); for(int i = 0; i < N; i++) { arr[i] = Long.parseLong(s[i]); sum += arr[i]; } // 현재값 * (총합 - 현재값) 구한 후 나머지 연산 long res = 0; for(int i = 0; i < N; i++) { sum -= arr[i]; res += (arr[i] * sum); res %= 1000000007; } System.out.println(res); } }
#include <iostream> #define fastio ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr) #define endl '\n' using namespace std; int main() { fastio; // 수열의 개수 입력 int N; cin >> N; long sum = 0; long arr[N]; // 수열 입력 및 수열의 총합 구하기 for(int i = 0; i < N; i++) { cin >> arr[i]; sum += arr[i]; } // 현재값 * (총합 - 현재값) 구한 후 나머지 연산 long res = 0; for(int i = 0; i < N; i++) { sum -= arr[i]; res += (arr[i] * sum); res %= 1000000007; } cout << res << endl; return 0; }
fun main(args: Array<String>) = with(System.`in`.bufferedReader()) { // 수열의 개수 입력 var N = readLine().toInt() var sum: Long = 0 var arr = Array<Long>(N, {0}) // 수열 입력 및 수열의 총합 구하기 var str = readLine().split(" ") for(i in 0 until N) { arr[i] = str[i].toLong() sum += arr[i] } // 현재값 * (총합 - 현재값) 구한 후 나머지 연산 var res: Long = 0 for(i in 0 until N) { sum -= arr[i] res += (arr[i] * sum) res %= 1000000007 } println(res) }
from sys import stdin def main(): # 수열의 개수 입력 N = int(stdin.readline()) sum = 0 arr = [0] * N # 수열 입력 및 수열의 총합 구하기 str = stdin.readline().split(' ') for i in range(N): arr[i] = int(str[i]) sum = sum + arr[i] # 현재값 * (총합 - 현재값) 구한 후 나머지 연산 res = 0 for i in range(N): sum = sum - arr[i] res = res + (arr[i] * sum) res = res % 1000000007 print(res) if __name__ == "__main__": main()
import Foundation func main() { // 수열의 개수 입력 var N = Int(readLine()!)! var sum: Int64 = 0 var arr = Array<Int64>(repeating: 0, count: N) // 수열 입력 및 수열의 총합 구하기 var str = readLine()!.split(separator: " ") for i in 0..<N { arr[i] = Int64(str[i])! sum += arr[i] } // 현재값 * (총합 - 현재값) 구한 후 나머지 연산 var res: Int64 = 0 for i in 0..<N { sum -= arr[i] res += (arr[i] * sum) res %= 1000000007 } print(res) } main()