아직 만들고 있는 페이지입니다.

이 페이지는 아직 만드는 중입니다. 보이는 내용은 바뀔 수 있습니다.

행복

시간 제한2초메모리 제한512 MB

요약
지폐 여러 장을 넣고 빼는 갱신이 있을 때마다 1부터 전체 합까지의 모든 값을 부분집합 합으로 만들 수 있는지 판정한다.
난이도

보통10점 중 7점

유형
그리디, 정렬, 수학, 구현
정답자
아직 제출이 없습니다

문제

X 나라의 화폐 체계는 조금 이상하다. 1부터 M까지의 모든 정수 값을 가지는 지폐가 있다. X 나라의 상점에는 또 다른 이상한 규칙이 있다. 손님은 거스름돈을 받을 수 없고, 팁을 남길 수도 없다. 즉 손님은 항상 구매 금액과 정확히 같은 값을 지불해야 한다. 가지고 있는 돈으로 정확한 금액을 만들 수 없다면 그 물건을 살 수 없다. 이 규칙이 손님들에게 얼마나 큰 불편을 주는지 상상해 보라.

Niya는 X 나라에서 온 소녀이다. 다른 모든 사람들과 마찬가지로 그녀도 위에서 설명한 규칙들과 끊임없이 싸운다. 그녀는 항상 자신의 지폐 집합을 알고 있다. 그 값이 a1, a2, ..., aN이라고 하자. 이 값들은 모두 1과 M 사이이고, 같은 값의 지폐를 여러 장 가지고 있을 수도 있다. 또한 값의 수열 a1, a2, ..., aN은 어떤 순서로도 정렬되어 있지 않다. Niya는 상점에 들어갔을 때, 총 가격이 1부터 자신이 가진 지폐 값의 합 a1 + a2 + ... + aN 사이의 어떤 수와도 같아지도록 상품을 임의로 조합하여 살 수 있다면 행복을 느낀다. 이 경우 쇼핑할 때 자신의 지폐로 살 수 있는지 없는지 복잡하게 계산할 필요 없이 전체 금액만 생각하면 된다.

비고: a1, a2, ..., aN을 오름차순으로 정렬하자. Si = 1 + a1 + a2 + ... + ai라고 하자. 1부터 a1 + a2 + ... + aN 사이의 모든 수를 중복 집합 a1, a2, ..., aN의 원소들의 합으로 나타낼 수 있기 위한 필요충분조건은 각 i > 1에 대해 부등식 Si ≥ ai+1이 성립하고 a1 = 1이라는 것이다.

예상대로 Niya의 지폐 집합은 구매할 때마다 그리고 월급을 받을 때마다 바뀐다. 그래서 그녀의 행복도 변한다. 이 소녀를 위해 프로그램을 하나 만들어 줄 수 있다. 프로그램은 Niya의 초기 지폐 집합과 일어나는 모든 사건(구매와 월급)을 입력으로 받는다. 프로그램은 처음에 그리고 각 사건 이후에 Niya가 행복한지 판별할 수 있어야 한다.

Niya는 돈이 하나도 없을 때도 행복을 느낀다는 점을 밝혀 둔다. 그럴 때는 쇼핑을 건너뛰고 조깅을 하러 가기 때문이다.

심사위원의 그레이더와 함께 컴파일될 함수 init()과 is_happy()를 작성하라. 이 함수들은 처음과 각 사건 이후에 Niya의 행복을 판별하는 데 쓰인다. 함수들은 매개변수로 Niya의 초기 지폐 집합과, 집합에서 제거되는(구매 시) 지폐 집합, 집합에 추가되는(월급 수령 시) 지폐 집합을 받는다.

채점 시스템에는 다음 함수들을 포함하는 파일 happiness.cpp를 제출해야 한다.

  • bool init(int coinsCount, long long maxCoinSize, long long coins[]).
  • bool is_happy(int event, int coinsCount, long long coins[]).

매개변수 설명:

  • coinsCount – 받거나(초기 집합 또는 월급) 버리는(쇼핑) 지폐의 수.

  • maxCoinSize – 지폐 한 장의 최댓값.

  • coins[] – 지폐의 값들이 임의의 순서로 주어지는 배열(인덱스는 0부터 시작).

  • event – 사건의 종류:

    • -1 – 쇼핑;
    • 1 – 월급 수령.

함수 init은 그레이더가 처음에 Niya의 초기 지폐 집합을 설정하기 위해 한 번 호출하고, 그다음 그레이더는 event = -1(쇼핑) 또는 event = 1(월급)로 is_happy를 Q번 호출한다. 각 호출 후 호출된 함수는 Niya가 현재 지폐 집합으로 행복하면 true, 그렇지 않으면 false를 반환해야 한다.

파일 happiness.cpp에는 함수 main()이 있어서는 안 되지만, 함수 init과 is_happy가 올바르게 동작하는 데 필요한 다른 선언과 함수는 있어도 된다. 프로그램 맨 처음에 #include "happiness.h"가 있어야 한다.

제한

Nc를 어느 순간의 Niya의 지폐 수, K를 어느 구매나 월급에 사용되는 지폐의 수라고 하자. 그러면 다음이 성립한다.

  • 0 ≤ Nc ≤ 200 000
  • 0 ≤ Q ≤ 100 000
  • 1 ≤ M ≤ 1012
  • 1 ≤ K ≤ 5

event = −1(쇼핑)인 is_happy의 모든 호출에서 coins[]에 주어지는 지폐 집합은 현재 Niya의 지폐 집합의 부분집합임이 보장된다.

예제1

  1. 예제 1

    입력
    5 100
    4 8 1 2 16
    2
    -1 2 2 8
    1 3 7 9 2
    
    예상 출력
    1
    0
    1