Skip to main content

Inclusion_And_Exclusion

BOJ 35108 ๊ฒŒ๊ตญ์ง€

·433 words·3 mins
๐Ÿ“ ๋ฌธ์ œ ์ •๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/35108 ๐Ÿง ๊ด€์ฐฐ ๋ฐ ์ ‘๊ทผ # $N$์ด 2500์ด๋‹ˆ๊นŒ ๋ญ”๊ฐ€ ์ œ๊ณฑ๋กœ๊ทธ?๊นŒ์ง„ ๋Œ์ง€ ์•Š์„๊นŒ ์‹ถ๋‹ค. ์Œ, ์–ด๋–ป๊ฒŒ ์žก์œผ๋ฉด ์ข‹์„์ง€ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ, ์ € ์ฃผ์–ด์ง„ ๊ฒŒ๊ตญ์ง€ ๊ทธ๋ž˜ํ”„์—์„œ ์•ˆ์ชฝ์˜ ๋„ค๋ชจ์ค‘ ์™ผ์ชฝ ์œ„๋ถ€ํ„ฐ ๋ฐ˜์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ $1, 2, 3, 4$ ๋ผ๊ณ  ํ•˜๋ฉด, $2, 4$๋ฒˆ ์ •์ ์„ ๊ธฐ์ค€์œผ๋กœ ์นด์šดํŒ…ํ•˜๊ณ ์‹ถ๊ฒŒ ์ƒ๊ธฐ๊ธด ํ–ˆ๋‹ค. ์ผ๋‹จ ์˜ˆ์ œ ๊ทธ๋ž˜ํ”„๋ฅผ ๊ทธ๋ ค๋ณด์ž. ![[Drawing 2026-03-07 09.54.26.excalidraw.png]] ์—ฌ๊ธฐ์„œ ์ € ๊ฒŒ๊ตญ์ง€๋ชจ์–‘์„ ์ฐพ์•„์•ผ ํ•˜๋Š”๋ฐ… $1, 2, 3, 4$๋ฅผ ๊ธฐ7์ค€์œผ๋กœ ํ•˜๋ฉด $1, 2, 4$์— $5, 7, 6$์„ ๋ถ™์ด๊ฑฐ๋‚˜, $6, 7, 5$๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋‘๊ฐ€์ง€๊ฐ€ ์žˆ๊ฒ ๋‹ค. ์–ด.. ์ •์ ์„ ๊ธฐ์ค€์œผ๋กœ ์„ธ๋ ค๊ณ  ํ•˜๋‹ˆ ์ข€ ๊นŒ๋‹ค๋กœ์šด๊ฑฐ ๊ฐ™๊ธฐ๋„..? ๊ทธ๋Ÿฌ๋ฉด ๊ฐ„์„ ์„ ๊ธฐ์ค€์œผ๋กœ..? ๊ทธ๋Ÿฌ๋ฉด ์•„๋ฌด๋ž˜๋„ ์–‘์ชฝ์— ๋‚ ๊ฐœ๊ฐ€ ๋ถ™์–ด์žˆ๋Š” ๊ฐ„์„ ์œผ๋กœ ์ƒ๊ฐํ•˜์ž. ํฌ์•„์•„์•„์•… ์ด๋ž˜๋„ ์•ˆ๋˜๋Š”๋ฐ ์ผ๋‹จ ๋‘ ๊ฐ„์„ ์„ ๊ณจ๋ผ์„œ ์‚ฌ์ดํด์„ ๊ณ ์ •์‹œํ‚ค๋Š”๊ฑด ๋งž๋Š”๊ฑฐ๊ฐ™๋‹ค. ์ž‰ ์ด๋Ÿฌ๋ฉด ๊ฑ ํฌํ•จ๋ฐฐ์ œ๋กœ ๋˜๋Š”๊ฑฐ ์•„๋‹Œ๊ฐ€? ๊ทธ๋Ÿฌ๋ฉด ๋‘ ์ •์ ์— ์ค‘๋ณต๋˜๋Š” ์ •์ , ์„ธ ์ •์ ์— ์ค‘๋ณต๋˜๋Š” ์ •์  ๋ญ ๊ทธ๋Ÿฐ๊ฒŒ ํ•„์š”ํ•œ๊ฑฐ๊ฐ™์€๋ฐ… ๋น„ํŠธ์…‹์œผ๋กœ ํ•˜๋ฉด ๋ ๋ผ๋‚˜? $O(M^2N/64)$ ์ •๋„์ธ๊ฑฐ๊ฐ™์€๋ฐ;; ์ผ๋‹จ ์งœ๋ณด์ž ์ข€ ๋นก๋นกํ•˜๋‹ค. ์ „์ฒ˜๋ฆฌ๋ฅผ ์ž˜ ํ•˜๋ฉด ์‹œ๊ฐ„ ๋‚ด๋กœ ๋“ค์–ด๊ฐ„๋‹ค. Clang์ด ํ›จ ๋น ๋ฅด๋„ค. ์™œ์ง€? ๐Ÿ’ป ํ’€์ด # ์ฝ”๋“œ (C++): void solve(){ int N, M; cin >> N >> M; vector<pii> edges; vector<bitset<2500>> con(N); rep(i, 0, M){ int u, v; cin >> u >> v; u--; v--; edges.push_back({u, v}); con[u][v] = 1; con[v][u] = 1; } vector<ll> cnt1(N); rep(i, 0, N) cnt1[i] = con[i].count(); vector<vector<bitset<2500>>> con2(N, vector<bitset<2500>>(N)); rep(i, 0, N) rep(j, i+1, N) con2[i][j] = con2[j][i] = con[i]&con[j]; vector<vector<ll>> cnt2(N, vector<ll>(N)); rep(i, 0, N) rep(j, i+1, N) cnt2[i][j] = cnt2[j][i] = con2[i][j].count(); auto calc = [&](int v1, int v2, int v3, int v4) -> ll { auto &b1 = con[v1], &b2 = con[v2], &b3 = con[v3]; ll n1 = cnt1[v1] - (con[v1][v2] + con[v1][v3] + con[v1][v4]); ll n2 = cnt1[v2] - (con[v2][v1] + con[v2][v3] + con[v2][v4]); ll n3 = cnt1[v3] - (con[v3][v1] + con[v3][v2] + con[v3][v4]); ll n12 = cnt2[v1][v2] - (con2[v1][v2][v3] + con2[v1][v2][v4]); ll n23 = cnt2[v2][v3] - (con2[v2][v3][v1] + con2[v2][v3][v4]); ll n31 = cnt2[v3][v1] - (con2[v3][v1][v2] + con2[v3][v1][v4]); bitset<2500> b123 = b1&b2&b3; ll n123 = b123.count() - b123[v4]; return n1*n2*n3 - (n12*n3 + n23*n1 + n31*n2) + 2*n123; }; ll ans = 0; rep(i, 0, M) rep(j, i+1, M){ auto [a, b] = edges[i]; auto [c, d] = edges[j]; if(a == c || a == d || b == c || b == d) continue; if((!con[a][c] || !con[b][d]) && (!con[a][d] || !con[b][c])) continue; ll ret = 0; ret += calc(a, b, c, d); ret += calc(b, c, d, a); ret += calc(c, d, a, b); ret += calc(d, a, b, c); if(con[a][c] && con[b][d]) ans += ret; if(con[a][d] && con[b][c]) ans += ret; } cout << ans/2; } ๐Ÿ”’ ๊ตฌํ˜„ ์ฝ”๋“œ ์ž ๊ธˆ

BOJ 18830 ํ•˜์ดํผ ์ˆ˜์—ด๊ณผ ํ•˜์ดํผ ์ฟผ๋ฆฌ

·387 words·2 mins
๐Ÿ“ ๋ฌธ์ œ ์ •๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/18830 ๐Ÿง ๊ด€์ฐฐ ๋ฐ ์ ‘๊ทผ # 11์ฐจ์›์ธ๊ฒŒ ์กฐ๊ธˆ ์ด์Šˆ์ด๋ฏ€๋กœ, ๊ฐ„๋‹จํ•˜๊ฒŒ 3์ฐจ์›์ •๋„๋กœ ์ƒ๊ฐํ•ด๋ณด์ž. 2์ฐจ์›์ด๋ฉด ๊ทธ๋ƒฅ ๋ˆ„์ ํ•ฉ ๋ฐฐ์—ด์—์„œ $S(a_2, b_2) - S(a_1, b_2) - S(a_2, b_1) + S(a_1, b_1)$์ด์—ˆ๋˜ ๊ฒƒ์ด ๊ธฐ์–ต๋‚œ๋‹ค. $a_1, b_1, c_1, a_2, b_2, c_2$๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. $a_1 \leq \alpha \leq a_2, b_1 \leq \beta \leq b_2, c_1 \leq \gamma \leq c_2$ ์ธ ์–ด์ฉŒ๊ตฌ์— ๋Œ€ํ•ด ํ•ฉ์„ ์ถœ๋ ฅํ•œ๋‹ค. ์ด๋ฅผ ๋ˆ„์ ํ•ฉ์œผ๋กœ ์ƒ๊ฐํ•˜๋ฉด, $S(a_2, b_2, c_2) - S(a_1, b_2, c_2) - S(a_2, b_1, c_2) - S(a_2, b_2, c_1) + S(a_1, b_1, c_2) + S(a_1, b_2, c_1) + S(a_2, b_1, c_1) - S(a_1, b_1, c_1)$ ์ธ ๊ฒƒ ๊ฐ™๋‹ค! ์•„๋‹˜๋ง๊ณ  ์•”ํŠผ $n$์ฐจ์›์ผ๋•Œ ๋ˆ„์ ํ•ฉ ๋ฐฐ์—ด์„ ๊ตฌํ•ด๋‘”๋‹ค๋ฉด $2^n$์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋กœ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ์ฟผ๋ฆฌ๊ฐ€ 4๋งŒ๊ฐœ์ด๋ฏ€๋กœ $40000 * 2048 = 81920000$์ด๋ฏ€๋กœ ์ถฉ๋ถ„ํžˆ ๋Œ ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋ˆ„์ ํ•ฉ ๋ฐฐ์—ด์„ ๋งŒ๋“œ๋Š”๊ฒŒ $O(2^n * mno...w)$ ๋ผ์„œ ์ด๊ฒŒ 20์–ต์ธ๋ฐ… ํฌํ•จ๋ฐฐ์ œ๋กœ ๊ตฌํ•˜์ง€ ๋ง๊ณ , ์ฐจ์›์— ๋Œ€ํ•ด์„œ ๊ตฌํ•˜๊ณ  ๋ฐ€์–ด๋ฒ„๋ฆฌ์ž. ๐Ÿ’ป ํ’€์ด # ์ฝ”๋“œ (C++): const int cdim = 11; using v11 = array<int, cdim>; v11 dim, sz; int totSz; vector<ll> A, pfsum; int point_to_idx(const v11 &point){ int idx = 0; rep(d, 0, cdim) idx += point[d] * sz[d]; return idx; } vector<ll> make_prefix_sum(int cd = 0, v11 cp = {}){ vector<ll> res; if(cd == cdim){ int idx = point_to_idx(cp); res.push_back(A[idx]); return res; } rep(i, 0, dim[cd]){ cp[cd] = i; vector<ll> tmp = make_prefix_sum(cd+1, cp); if(res.empty()) res = tmp; else{ rep(j, 0, tmp.size()) res.push_back(res[(i-1) * sz[cd] + j] + tmp[j]); } } cp[cd] = 0; return res; } void solve(){ rep(i, 0, cdim) cin >> dim[i]; sz[cdim-1] = 1; rrep(d, cdim-1, 0) sz[d] = sz[d+1] * dim[d+1]; totSz = sz[0] * dim[0]; A.resize(totSz); pfsum.resize(totSz, 0); rep(i, 0, totSz) cin >> A[i]; pfsum = make_prefix_sum(); int Q; cin >> Q; while(Q--){ v11 L, R; rep(d, 0, cdim) cin >> L[d]; rep(d, 0, cdim) cin >> R[d]; rep(d, 0, cdim) L[d]--, R[d]--; ll ans = 0; rep(mask, 0, (1<<cdim)){ v11 point = R; bool add = true, flag = true; rep(d, 0, cdim) if(mask & (1<<d)){ point[d] = L[d]-1; add = !add; if(point[d] < 0){ flag = false; break; } } if(!flag) continue; int idx = point_to_idx(point); if(add) ans += pfsum[idx]; else ans -= pfsum[idx]; } cout << ans << "\n"; } } ๐Ÿ”’ ๊ตฌํ˜„ ์ฝ”๋“œ ์ž ๊ธˆ