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

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

주인장과 마법의 수

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

요약
삼각형 모양으로 배치된 이진 문자열에서 1의 위치만 주어질 때, 비트 연산 프로그램을 거쳐 만든 b_j들로 각 질의가 선택한 b_j들의 OR의 1의 개수를 구한다.
난이도

어려움10점 중 9점

유형
비트 연산, 구현, 수학, 완전 탐색
정답자
아직 제출이 없습니다

문제

주인장은 nn개의 마법의 수를 가지고 있다. ii번째 수 a_ia\_i는 길이가 ii인 이진 문자열로 나타낼 수 있고, 이 문자열은 앞에 0이 여러 개 붙어도 된다. 이 이진 문자열들을 뒤집어서 이어 붙이면 길이가 n(n+1)2\frac{n (n + 1)}{2}인 긴 문자열 ss가 된다. s[i(i−1)2]s\left[\frac{i (i - 1)}{2}\right]부터 s[i(i+1)2−1]s\left[\frac{i (i + 1)}{2} - 1\right]까지의 부분 문자열은 a_ia\_i의 이진 표현이며, 가장 낮은 자리부터 가장 높은 자리 순서로 되어 있다. 긴 문자열 ss의 인덱스는 0부터 시작한다.

어느 날, 린은 주인장의 마법의 수를 프로그램에 입력해서 nn개의 새로운 마법의 수를 만들려고 한다. ii번째 새로운 수는 b_ib\_i이다. 다음은 C와 비슷한 언어로 작성된 프로그램의 코드이다.

for (int i = 1; i <= n; i++) {
  b[i] = 0,
  flag[i] = 0;
}

for (int i = 1; i <= n; i++) {
  for (int j = 1; j <= n; j++) {
    if (((1 << (j - 1)) & a[i]) > 0) {
      if (!flag[i]) {
        b[i] = b[j],
        flag[i] = 1;
      } else {
        b[i] = b[i] & b[j];
      }
    }
  }
  b[i] = b[i] ^ (1 << (i - 1));
}

위 코드에서 "x << y"는 왼쪽 시프트 연산이며, x에 2y2^{\texttt{y}}를 곱하는 것과 같다. "x & y"는 비트 AND, "x ^ y"는 비트 XOR이다. 수 a_ia\_i와 b_ib\_i는 임의로 많은 비트를 가질 수 있다고 가정한다.

그 후, 린은 qq개의 질문을 하려고 한다. ii번째 질문은 수 c_ic\_i이며, 이는 길이가 len_i\mathit{len}\_i인 이진 문자열로 나타낼 수 있고 앞에 0이 여러 개 붙어도 된다. 이 이진 문자열들을 뒤집어서 이어 붙이면 길이가 L_qL\_q인 긴 문자열 tt가 되며, 여기서 L_k=∑_i=1klen_iL\_k = \sum\limits\_{i = 1}^{k} \mathit{len}\_i이다. t[L_i−1]t\left[L\_{i - 1}\right]부터 t[L_i−1]t\left[L\_i - 1\right]까지의 부분 문자열은 c_ic\_i의 이진 표현이며, 가장 낮은 자리부터 가장 높은 자리 순서로 되어 있다. 긴 문자열 tt의 인덱스는 0부터 시작한다.

각 질문에 대해 린은 일리아에게 수 d_id\_i를 계산해 달라고 부탁한다.

for (int i = 1; i <= q; i++) {
  d[i] = 0;
  for (int j = 1; j <= min (n, len[i]); j++) {
    if (((1 << (j - 1)) & c[i]) > 0) {
      d[i] = d[i] | b[j];
    }
  }
}

여기서 "x | y"는 비트 OR이다. 수 c_ic\_i와 d_id\_i는 임의로 많은 비트를 가질 수 있다고 가정한다.

ii번째 질문의 답은 d_id\_i의 이진 표현에서 1의 개수이다. 일리아가 모든 질문에 답하도록 도와주자!

입력

입력의 첫째 줄에는 마법의 수의 개수와 긴 문자열 ss에 있는 1의 개수를 나타내는 두 정수 nn과 mm이 주어진다 (1≤n≤50001 \leq n \leq 5000, 1≤m≤1061 \leq m \leq 10^6).

둘째 줄에는 mm개의 정수가 주어지며, ii번째 정수 p_ip\_i는 s[p_i]=1s[p\_i] = 1임을 나타낸다. ss의 나머지 자리는 모두 0이다 (0≤p_i<n(n+1)20 \leq p\_i < \frac{n (n + 1)}{2}, 모든 p_ip\_i는 서로 다르다).

셋째 줄에는 질문의 개수와 긴 문자열 tt에 있는 1의 개수를 나타내는 두 정수 qq와 rr이 주어진다 (1≤q≤50001 \le q \le 5000, 1≤r≤1061 \le r \le 10^6).

넷째 줄에는 qq개의 정수가 주어지며, ii번째 정수 len_i\mathit{len}\_i는 ii번째 질문 c_ic\_i의 이진 표현의 길이를 나타낸다 (1≤len_i≤1091 \leq \mathit{len}\_i \leq 10^9). L_q=∑_i=1qlen_iL\_q = \sum\limits\_{i = 1}^{q} \mathit{len}\_i가 10910^9 이하임이 보장된다.

다섯째 줄에는 rr개의 정수가 주어지며, ii번째 정수 z_iz\_i는 t[z_i]=1t[z\_i] = 1임을 나타낸다. tt의 나머지 자리는 모두 0이다 (0≤z_i<L_q0 \le z\_i < L\_q, 모든 z_iz\_i는 서로 다르다).

출력

각 질문 ii에 대해 d_id\_i의 이진 표현에서 1의 개수를 한 줄에 하나씩 출력한다.

예제1

  1. 예제 1

    입력
    3 4
    0 1 4 5
    3 6
    2 3 3
    0 1 2 4 6 7
    
    예상 출력
    2
    3
    3