내용으로 건너뛰기
테페리넷
사용자 도구
등록
로그인
사이트 도구
검색
도구
문서 보기
Fold/unfold all
역링크
미디어 관리자
사이트맵
등록
로그인
>
미디어 관리자
사이트맵
현재 위치:
테페리넷
»
Problem Solving
»
문제
»
백준 온라인 저지 (BOJ)
»
배열의 힘
ps:problems:boj:8462
이 문서는 읽기 전용입니다. 원본을 볼 수는 있지만 바꿀 수는 없습니다. 문제가 있다고 생각하면 관리자에게 문의하세요.
====== 배열의 힘 ====== ===== 풀이 ===== * 온라인 쿼리로는 구간에서 저 값을 빠르게 계산하는 방법이 잘 떠오르지 않는다. * 오프라인 쿼리로 처리해서 [[ps:Mo's algorithm]]을 사용하려고 생각하자. * 어떤 구간에 대해서, 각 숫자의 등장 횟수 Ks와 구하는 값을 저장해두자. 구간을 한 칸 더 늘릴때는, 늘어난 구간의 값이 x라면, 기존 정답에서 Kx*Kx*x 를 빼고 Kx를 1 증가시킨 다음에 다시 Kx*Kx*x 를 더하면 된다. 순서를 좀 바꾸면 정답에 (Kx+1)*(Kx+1)*x - Kx*Kx*x = (2*Kx+1)*x를 더한 뒤 Kx를 1 증가시키는 것. 이것은 O(1)에 해결된다 * 구간을 한칸 줄이는 것도 똑같은 과정으로 O(1)에 해결된다 * 따라서 이 두가지 연산으로 [[ps:Mo's algorithm]]을 돌리면, 총 시간복잡도는 쿼리 정렬에 드는 O(qlogq)과 쿼리 처리에 걸리는 O( (n+q)*sqrt(n))*O(1) 을 합친 O(qlogq + (n+q)*sqrt(n))이 된다. ===== 코드 ===== <dkpr py> """Solution code for "BOJ 8462. 배열의 힘". - Problem link: https://www.acmicpc.net/problem/8462 - Solution link: http://www.teferi.net/ps/problems/boj/8462 """ import sys from teflib import mosalgo def main(): # pylint: disable=unused-variable n, t = [int(x) for x in sys.stdin.readline().split()] a = [int(x) for x in sys.stdin.readline().split()] queries = [] for i in range(t): l, r = [int(x) for x in sys.stdin.readline().split()] queries.append((l - 1, r, i)) count = [0] * (max(a) + 1) def add(beg, end, ans): for a_i in a[beg:end]: ans += (count[a_i] * 2 + 1) * a_i count[a_i] += 1 return ans def delete(beg, end, ans): for a_i in a[beg:end]: count[a_i] -= 1 ans -= (count[a_i] * 2 + 1) * a_i return ans answers = mosalgo.mo(queries, add, delete) print(*answers, sep='\n') if __name__ == '__main__': main() </dkpr> * Dependency: [[:ps:teflib:mosalgo#mo|teflib.mosalgo.mo]] {{tag>BOJ ps:problems:boj:플래티넘_2}}
ps/problems/boj/8462.txt
· 마지막으로 수정됨: 2021/05/04 10:43 저자
teferi
문서 도구
문서 보기
역링크
Fold/unfold all
맨 위로