1. ๋ฌธ์ ์ค๋ช
2. ์ ๊ทผ ๋ฐฉ์
- sum[i] [j] = (0,0) ~ (i,j) ๊น์ง์ ํฉ์ผ๋ก ๋ํ๋๋ค.
i = 0 ์ธ ์ด์ ์ด์ ํ์ ์ต๋ ๊ฐ์ ์ ์ฅํ๋๋ก ํด์, ๋์ ํฉ์ด ๊ณ์ ์ด์ด์ง๋๋ก ๋ง๋ค์๋ค. - ํ์ง๋ง ๊ตฌ๊ฐ ํฉ (a,b) ~ (c,d)๋ฅผ ๊ตฌํ๋ผ ํจ์, a < x < c , b < y < d ์ ์ธ๋ฑ์ค๋ฅผ ๊ฐ์ง ๋ฐฐ์ด๋ค์ ํฉ์ ๊ตฌํ๋ ๋ง์ด๋ค. ๋ฐ๋ผ์ ๋จ์ํ ๋์ ํฉ์ด ์๋, ๋ฐฐ์ด ์์ ๋ค๋ชจ๋ ๋ถ๋ถ์ ๊ตฌํด์ผ ํ๋ค. ์๋ฅผ ๋ค๋ฉด
- ๊ทธ๋์ ๋๋ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํ๋ค.
๋ค์๊ณผ ๊ฐ์ด ํธ๋ฅธ์ ํ๊ดํ์์ ๋ณด๋ผ์ ํ๊ดํ ๊ฐ์ ๋นผ์ฃผ๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ค์ ๋ ํ๋ค.
3. ์ฝ๋ ๋ถ์
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int [][] s = new int [N+1][N+1];
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j <= N; j++) {
s[i][j] = j==0? s[i-1][N] : s[i][j-1] + Integer.parseInt(st.nextToken());
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int sX = Integer.parseInt(st.nextToken());
int sY = Integer.parseInt(st.nextToken());
int eX = Integer.parseInt(st.nextToken());
int eY = Integer.parseInt(st.nextToken());
int sum = 0;
for (int j = sX; j <= eX; j++) {
sum += (s[j][eY] - s[j][sY-1]);
}
sb.append(sum).append("\n");
}
System.out.println(sb);
}
}
(1) ์์ฌ์ด ์
๊ตฌ๊ฐ ํฉ์ ๊ตฌํ๋๋ฐ, ๋ฐ๋ณต๋ฌธ์ด ๋ค์ด๊ฐ์ ๋๋ฆฌ๋ค. M^2๋ ์๋์ง๋ง, ๊ทธ๋์ ์ต์ ์ ๊ฒฝ์ฐ์๋ M*N์ ์๊ฐ๋ณต์ก๋๊ฐ ๋ ๋ค. N = 1024 ์ด์ง๋ง, M = 10^5 ์ฌ์ ๊ฐ๊น์ค๋ก 1์ต ๋ฒ ์ฐ์ฐ ์ ์ชฝ์ผ๋ก ๋ค์ด์ฌ ๊ฒ ๊ฐ๋ค.
4. ์ฑ์ฅ ํ๊ธฐ
ํด๋น ๋ฌธ์ ์์ ์ํ๋ ๊ตฌ๊ฐํฉ์ด ๋ค๋ชจ๋ ๋ฐฐ์ด์ ๋ถ๋ถ์ ๊ตฌํ๋ผ๋ ๋ป์ด๋ฏ๋ก, ๊ทธ๊ฒ์ ์ด์ฉํ์ฌ, ๋์ ํฉ์ ๋ค๋ฅด๊ฒ ์๊ฐํด๋ณธ๋ค.
ํธ๋ฅธ์ ํ๊ดํ์ด ์น ํด์ง ๋ฒ์๊น์ง์ ๋์ ํฉ์ ์๊ฐํด๋ณด๋ฉด,
$$
(์ด๋ก์ ํ๊ดํ + ๋นจ๊ฐ์ ํ๊ดํ - ๊ฒน์น๋ ๋ถ๋ถ) + ํธ๋ฅธ์ ํ๊ดํ์ ์๋ ๊ฐ
$$
์ด๋ค.
์ด๋ฅผ ๊ณต์์ผ๋ก ํํํ๋ฉด,
$$
sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + arr[i][j]
$$
์ด๋ค.
์ด๋ฐ ์์ผ๋ก ๋์ ํฉ ๋ํ (0,0) ~ (i, j) ๊น์ง์ ๋ค๋ชจ๋ ๋์ ํฉ์ ๊ฐ๋
์ผ๋ก ๋ฐ๊ฟ ์๊ฐํ๋ค. ๊ทธ๋ฌ๋ฉด ๋์ ํฉ ๋ฐฐ์ด์ ๊ฐ์ ๋ค์๊ณผ ๊ฐ์ด ์ฑ์์ง๋ค.
์ด์ ์ฌ๊ธฐ์ ์ํ๋ ๊ตฌ๊ฐ ํฉ์ ๊ตฌํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น?
๋ง์ฝ (3,3) ~ (4,4) ๋์ ํฉ์ ๊ตฌํด์ผ ํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํ ์ ์์ ๊ฒ์ด๋ค. ๋จผ์ ์ผ๋ฐ ๋ฐฐ์ด์์ ์๊ฐํด๋ณด์
ํ๋์ ๋ถ๋ถ์ ๊ตฌํ๋ ค๋ฉด ์ ์ฒด ๋์ ํฉ - ์ด๋ก์ ๋ถ๋ถ (๊ฐ๋ก) - ์ด๋ก์ ๋ถ๋ถ (์ธ๋ก) + ์ด๋ก์ ๊ฒน์น๋ ๋ถ๋ถ ์ด๋ค.
์ด๋ฅผ ๋์ ํฉ์์ ๋ณด๋ฉด
๋นจ๊ฐ์ - (์ด๋ก์ 1 + ์ด๋ก์ 2) + ์ฃผํฉ์ ์ด๋ค.
์์์ผ๋ก ํํ ํ๋ฉด, ((startX, startY) ~ (endX,endY) ๊น์ง์ ๊ตฌ๊ฐ ํฉ ๊ตฌํ๊ธฐ)
$$
sum[endX][endY] - (sum[startX-1][endY] + sum[endX][startY-1])+sum[startX-1][startY-1]
$$
์ด๋ค.
์ด๋ฅผ ์ด์ ์ฝ๋๋ก ๊ตฌํํ๋ฉด ๋๋ค.
5. ๋ค์ ํ๊ธฐ
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int [][] sum = new int [N+1][N+1];
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= N; j++) {
sum[i][j] = sum[i][j-1] + sum[i-1][j] - sum[i-1][j-1] + Integer.parseInt(st.nextToken());
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int sx = Integer.parseInt(st.nextToken());
int sy = Integer.parseInt(st.nextToken());
int ex = Integer.parseInt(st.nextToken());
int ey = Integer.parseInt(st.nextToken());
sb.append((sum[ex][ey] - sum[ex][sy-1] - sum[sx-1][ey] + sum[sx-1][sy-1])).append("\n");
}
System.out.println(sb);
}
}