๐ ๋ฌธ์ ์ค๋ช
N๊ฐ์ ์ซ์๊ฐ ์ฃผ์ด์ง ๋, ์ฐ์๋ ๋ถ๋ถ ๊ตฌ๊ฐ ํฉ์ด M์ผ๋ก ๋๋์ด ๋จ์ด์ง๋ ๊ตฌ๊ฐ์ ๊ฐ์
๋ฐฐ์ด [1, 2, 3, 1, 2]์์ 3์ผ๋ก ๋๋์ด ๋จ์ด์ง๋ ๊ตฌ๊ฐ?
๐ [1, 2], [1, 2, 3], [3], [2, 3, 1], [3, 1, 2], [1, 2] = `7๊ฐ`
- N: ์ซ์ ๊ฐ์ (N ≤ ๋ฐฑ๋ง)
- M: ๋๋๋ ์ (M <= 1,000)
- Aโ <= 1์กฐ
์ซ์๊ฐ ๋ฐฑ๋ง ๊ฐ๊น์ง ์ฃผ์ด์ง ์ ์์ด์ `O(NLogN) ์ดํ`์ ์๊ฐ ๋ณต์ก๋๋ก ํ์ด์ผ ์๊ฐ ์ด๊ณผ๊ฐ ๋์ง ์๋๋ค.
๋ถ๋ถ ๊ตฌ๊ฐ์ ๊ฐ์๋ฅผ ๊ตฌํด์ผ ํ๋ฏ๋ก ๊ณ์ฐ ํ ๋๋ง๋ค ํฉ์ ๊ตฌํด ๋๊ฐ๋ ๊ฒ ์๋, `๋์ ํฉ`์ ์ด์ฉํด ํ์ด์ผ ํ๋ค.
M์ผ๋ก ๋๋์ด ๋จ์ด์ง๋, ์ฆ M์ผ๋ก ๋๋ ๋๋จธ์ง๊ฐ 0์ธ ๊ตฌ๊ฐ์ ๊ตฌํ๋ ค๋ฉด `(A+B) % M == 0` ์์์ผ๋ก ํ๋ฉด ๋๋ค.
๐ ๋๋จธ์ง ์ฐ์ฐ
(A+B)%C ๋ {(A%C) + (B%C)} % C์ ๋์ผํ๋ค.
์ฐ๋ฆฌ๋ ๋๋จธ์ง ์ฐ์ฐ์ ๊ฒฐ๊ณผ ๊ฐ์ด 0์ธ ๊ตฌ๊ฐ์ ๊ตฌํด์ผ ํ๋ฏ๋ก `{(A%C) + (B%C)} % C = 0` ์์์ ์ด์ฉํ๋ฉด ๋๋ค.
์๊ฐ ํ๊ธฐ
[1, 2, 3, 1, 2] ๋ฐฐ์ด์ด ์ฃผ์ด์ก์ ๋, ๋์ ํฉ์ ๊ตฌํ๋ฉด [1, 3, 6, 7, 9]๊ฐ ๋๋ค.
- ๊ฐ ์์๋ 0๋ถํฐ ~ ํ์ฌ ์ธ๋ฑ์ค๊น์ง์ ํฉ์ ๋ํ๋ธ๋ค.
- ํน์ ์ธ๋ฑ์ค(j) ~ ํ์ฌ ์ธ๋ฑ์ค(i)์ ๋ถ๋ถํฉ์ `S[i] - S[j-1]`์ด ๋๋ค.
์ฆ, S[i] - S[j]๋ `j+1 ~ i` ๊น์ง์ ๊ตฌ๊ฐ ํฉ์ด๋ค. - `S[i]%M` ๊ฐ๊ณผ `S[j]%M` ๊ฐ์ด ๊ฐ์ ๊ฒฝ์ฐ, ๋๋จธ์ง ์ฐ์ฐ์์ (S[i] - S[j])%M์ 0์ด ๋๋ค.
์ฐ๋ฆฌ๋ ๋์ ํฉ์ ๊ตฌํ ๋๋ง๋ค ๋๋จธ์ง ์ฐ์ฐ์ ์ ์ฉํ ๊ฒฐ๊ณผ๋ฅผ ์ด์ฉํ๋ฉด ๋๋ค.
๋์ถํด๋ธ ๊ท์น์ ๊ฐ์ง๊ณ ์์ ๋ฅผ ์ดํด๋ณด๋ฉด,
- ๋์ ํฉ: [1, 3, 6, 7, 9]
- ๋๋จธ์ง ์ ์ฅ: [1, 0, 0, 1, 0]
์ด๋, ๋๋จธ์ง๊ฐ 0์ธ ๊ฒฝ์ฐ ์ฒ์๋ถํฐ ํด๋น ์ธ๋ฑ์ค๊น์ง์ ๋์ ํฉ์ด M์ผ๋ก ๋๋์ด ๋จ์ด์ง๋ค๋ ์๋ฏธ์ด๋ฏ๋ก,
๊ฒฐ๊ณผ ๊ฐ์ 0์ ๊ฐ์๋ฅผ ๋ํ๋ค.
๊ฐ์ ๋๋จธ์ง ๋ณ๋ก ์กฐํฉ์ ๊ตฌํ ํ ๋ํ๋ฉด ๋๋ค.
- ๋๋จธ์ง 1 = 2๊ฐ, `โCโ` = 1,
- ๋๋จธ์ง 0 = 3๊ฐ, `โCโ` = 3,
๋ฐ๋ผ์ ๊ตฌ๊ฐ์ ๊ฐ์๋ 3+1+3 = 7 ์ด๋ฏ๋ก ์์ ์ ๊ฒฐ๊ณผ๊ฐ๊ณผ ๋์ผํ๋ค.
๐ณ ์ ์ฒด ์์ค ์ฝ๋
import java.io.*;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
public class Main{
public static <Set> void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int [] remain = new int[m];
st = new StringTokenizer(br.readLine());
long prev =0;
for(int i = 0; i < n; i++) {
int cur =Integer.parseInt(st.nextToken());
remain[(int) ((prev + cur)%m)]++;
prev +=cur;
}
long count = remain[0];
for(int i = 0; i < m; i++) {
count+= (long) remain[i] *(remain[i]-1) / 2;
}
bw.write(count+"");
bw.flush();
bw.close();
}
}
โ ๋ถ๋ถ ์ฝ๋ ์ค๋ช
๋ณ์ & ๋ฐฐ์ด ์ด๊ธฐํ
public class Main{
public static <Set> void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int [] remain = new int[m];
st = new StringTokenizer(br.readLine());
long prev =0;
for(int i = 0; i < n; i++) {
int cur =Integer.parseInt(st.nextToken());
remain[(int) ((prev + cur)%m)]++;
prev +=cur;
}
...
- `n`: ์ซ์ ๊ฐ์
- `m`: ๋๋๋ ์
- `remain[]`: ๋์ ํฉ๋ณ m์ผ๋ก ๋๋ ๋๋จธ์ง ์ ์ฅ
- `prev`: ๋์ ํฉ ์ ์ฅ
prev ๋ณ์๋ฅผ `long` ํ์ ์ผ๋ก ์ ์ธํ ์ด์ โ
์ฃผ์ด์ง๋ ์ซ์์ ์ต๋ ๊ฐ์ด 1์กฐ์ด๋ฏ๋ก int ํ์ ์ผ๋ก ์ ์ธ ์ ์ค๋ฒํ๋ก์ฐ๊ฐ ๋ฐ์
int : ์ฝ 21์ต
long: ์ฝ 900๊ฒฝ
๋ฐ๋ณต๋ฌธ์ ๋๋ฉด์, `๋์ ํฉ (prev) + ํ์ฌ ๊ฐ`์ ๋๋จธ์ง๋ฅผ ๊ตฌํ๊ณ , remain ๋ฐฐ์ด์ ํด๋น ๋๋จธ์ง ๊ฐ์๋ฅผ 1 ์ฆ๊ฐ ํ๋ค.
๊ตฌ๊ฐ ๊ฐ์ ๊ตฌํ๊ธฐ
public class Main{
public static <Set> void main(String[] args) throws IOException {
...
long count = remain[0];
for(int i = 0; i < m; i++) {
count+= (long) remain[i] *(remain[i]-1) / 2;
}
bw.write(count+"");
bw.flush();
bw.close();
}
}
- `count`: ๊ตฌ๊ฐ ๊ฐ์ ์ ์ฅ
๋๋จธ์ง๊ฐ 0์ธ ๊ฒฝ์ฐ ๊ทธ ์์ฒด๋ก m์ผ๋ก ๋๋์ด ๋จ์ด์ง๋ฏ๋ก 0์ ๊ฐ์๋ก count์ ๋ํ๋ค. - remain ๋ฐฐ์ด์ ์ํํ๋ฉด์, ๋๋จธ์ง ๋ณ ์กฐํฉ ๊ฐ์๋ฅผ ๊ตฌํ ๊ฐ์ count์ ๋ํ๋ค.
- count ์ถ๋ ฅ ํ ํ๋ก๊ทธ๋จ ์ข ๋ฃ!
๐ ์กฐํฉ ๊ณต์
โCโ = (3*2) / (2*1) = 3
โCโ = (4*3) / (2*1) = 6count๋ฅผ long์ผ๋ก ์ ์ธํ ์ด์ โ
n์ ๊ฐ์๊ฐ ๋ฐฑ๋ง๊ฐ์ด๊ณ , ๋๋จธ์ง ๊ฐ์ด ์ ๋ถ ๋์ผํ ๊ฒฝ์ฐ, `count โ 5์ฒ์ต`์ด๋ฏ๋ก
โจ ๊ฒฐ๊ณผ
์ด ๋ฌธ์ ์ ํต์ฌ์ ๋๋จธ์ง ์ฐ์ฐ์ ํ์ฉํ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ค.
์ฒ์ ํ ๋ ๋๋จธ์ง ์ฐ์ฐ์ ๋ณํํ์ฌ ์ ๊ทผํ๋ ๋ฐฉ์์ ์๊ฐํ์ง ๋ชป ํ์ง๋ง,
ํด๋น ๋ฌธ์ ๋ฅผ ํตํด ๊ตฌ๊ฐํฉ๊ณผ ๋๋จธ์ง ์ฐ์ฐ์ ๋ํด ์ ๋ฆฝ ํ๊ณ ๊ฐ ์ ์์๋ค.