티스토리 뷰
문제
3673번: 나눌 수 있는 부분 수열
양의 정수로 이루어진 수열이 주어졌을 때, 연속하는 부분 수열의 합이 d로 나누어 떨어지는 것의 개수를 구하는 프로그램을 작성하시오. 예를 들어, 아래와 같은 수열의 부분 수열 중 4로 나누��
www.acmicpc.net
문제 풀이
1. n의 범위로 보아 연속된 부분수열의 합을 구하기 위해 누적합을 사용한다고 생각했습니다.
2. 시작점이 고정된 연속 부분수열의 합이 아니므로 구해야하는건 시작점을 s, 끝점을 e라 할 때, 구간[s,e]의 누적합이 (psum[e] - psum[s-1])%d ==0을 만족하는 (s,e)쌍을 찾는 것과 같았고, 이는 (psum[e] % d) == (psum[s - 1] % d)와 동치입니다.
3. 따라서 누적 합 psum[i]를 d로 나눈 나머지 배열(mod[])을 만들어서 누적합을 구할 때 마다 mod[psum[i] % d]의 값을 하나씩 올려줍니다.
4. k = (psum[i] % d)라 할 때, 구간 [0~ d - 1]을 만족하는 k에 대해 mod를 순회하며 그 값이 2보다 크거나 같은 경우 만족하는 인덱스들이 그 순서를 유지하며 (s,e)에 들어가는 것이므로 정답에 mod[k]C₂만큼 더해줍니다. (k가 0인 경우 구간[0 : 해당 인덱스]누적합의 나머지가 0인 것이므로 그 값은 위와 별개로 더해줍니다.)
코드
#include <bits/stdc++.h> using namespace std; typedef long long ll; int tc, d, n; vector<int> v; vector<ll> psum, mod; int main() { cin.tie(NULL); cout.tie(NULL); ios_base::sync_with_stdio(false); cin >> tc; while (tc--) { cin >> d >> n; v.clear(), v.resize(n + 1); psum.clear(), psum.resize(n + 1); mod.clear(), mod.resize(d); for (int i = 1; i <= n; i++) { cin >> v[i]; psum[i] = psum[i - 1] + v[i]; mod[psum[i] % d]++; } ll ans = 0; for (int k = 0; k < d; k++) { if (!k && mod[k]) ans += mod[k]; if (mod[k] >= 2) ans += (mod[k] * (mod[k] - 1)) / 2; } cout << ans << '\n'; } }
'Algorithm > BOJ' 카테고리의 다른 글
[백준 1981] 배열에서 이동 (0) | 2020.09.19 |
---|---|
[백준 3197] 백조의 호수 (0) | 2020.09.10 |
[백준 1655] 가운데를 말해요 (0) | 2020.09.06 |
[백준 17436] 소수의 배수 (0) | 2020.09.06 |
[백준 16402] 제국 (0) | 2020.09.05 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 시뮬레이션
- 동적계획법
- 프로그래머스 월간코드챌린지
- 위클리 챌린지
- 백준
- 유니온파인드
- 표 편집
- 카카오 2021
- 게임이론
- Kakaoblind
- DP
- 구현
- 이분탐색
- 2021 KAKAO BLIND
- 투포인터
- 카카오 2020 인턴십
- 파싱
- 카카오 표 편집
- 카카오 2차코딩테스트
- BFS
- 2022 카카오블라인드
- 2022 KAKAO BLIND RECRUITMENT
- 프로그래머스
- 2020 KAKAO BLIND RECRUITMENT
- 카카오 인턴십
- 프로그래머스 위클리 9주차
- 2022 카카오 블라인드 코딩테스트
- 2021 카카오 블라인드
- 트리
- 누적합
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함