๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ”ฅ PS(Problem Solving) ๐Ÿ”ฅ/BOJ

[BOJ] #1208 ๋ถ€๋ถ„์ˆ˜์—ด์˜ ํ•ฉ 2

by dar0m! 2021. 2. 4.
์‹œ๊ฐ„ ์ œํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ ์ •๋‹ต ๋น„์œจ
 1 ์ดˆ 256 MB 21.446 %
 

1208๋ฒˆ: ๋ถ€๋ถ„์ˆ˜์—ด์˜ ํ•ฉ 2

์ฒซ์งธ ์ค„์— ์ •์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” N๊ณผ ์ •์ˆ˜ S๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. (1 ≤ N ≤ 40, |S| ≤ 1,000,000) ๋‘˜์งธ ์ค„์— N๊ฐœ์˜ ์ •์ˆ˜๊ฐ€ ๋นˆ ์นธ์„ ์‚ฌ์ด์— ๋‘๊ณ  ์ฃผ์–ด์ง„๋‹ค. ์ฃผ์–ด์ง€๋Š” ์ •์ˆ˜์˜ ์ ˆ๋Œ“๊ฐ’์€ 100,000์„ ๋„˜์ง€ ์•Š๋Š”๋‹ค.

www.acmicpc.net

 

๋ฌธ์ œ

N๊ฐœ์˜ ์ •์ˆ˜๋กœ ์ด๋ฃจ์–ด์ง„ ์ˆ˜์—ด์ด ์žˆ์„ ๋•Œ, ํฌ๊ธฐ๊ฐ€ ์–‘์ˆ˜์ธ ๋ถ€๋ถ„์ˆ˜์—ด ์ค‘์—์„œ ๊ทธ ์ˆ˜์—ด์˜ ์›์†Œ๋ฅผ ๋‹ค ๋”ํ•œ ๊ฐ’์ด S๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

์ฒซ์งธ ์ค„์— ์ •์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” N๊ณผ ์ •์ˆ˜ S๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. (1 ≤ N ≤ 40, |S| ≤ 1,000,000) ๋‘˜์งธ ์ค„์— N๊ฐœ์˜ ์ •์ˆ˜๊ฐ€ ๋นˆ ์นธ์„ ์‚ฌ์ด์— ๋‘๊ณ  ์ฃผ์–ด์ง„๋‹ค. ์ฃผ์–ด์ง€๋Š” ์ •์ˆ˜์˜ ์ ˆ๋Œ“๊ฐ’์€ 100,000์„ ๋„˜์ง€ ์•Š๋Š”๋‹ค.

ํ•ด๊ฒฐ

key point, ๋ถ€๋ถ„์ง‘ํ•ฉ์„ ์žฌ๊ท€์ ์œผ๋กœ ์ฐพ๊ธฐ์—” N์ด ๋„ˆ๋ฌด ํฌ๊ธฐ ๋•Œ๋ฌธ์— ์ ˆ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆˆ๋‹ค.
  • ์ •์ˆ˜ N๊ฐœ๋ฅผ ํ™€์ˆ˜, ์ง์ˆ˜๋กœ ๋‚˜๋ˆ  ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. → seq
  • ๋น„ํŠธ๋งˆ์Šคํฌ๋ฅผ ํ™œ์šฉํ•ด ๋ถ€๋ถ„์ง‘ํ•ฉ์„ ๊ตฌํ•œ๋‹ค. → sub
  • ๋ฐ˜๋“œ์‹œ ์ •๋ ฌํ•œ๋‹ค.
    • ์ •๋ ฌ์„ ํ•ด์•ผ ๋ถ€๋ถ„์ง‘ํ•ฉ์„ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆˆ ์ด์œ ๊ฐ€ ์—†์–ด์ง!
  • ๋‘ ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋‰œ ๋ถ€๋ถ„์ง‘ํ•ฉ์„ ํˆฌ ํฌ์ธํ„ฐ๋ฅผ ํ™œ์šฉํ•ด ํ•ฉ์ด S๊ฐ€ ๋˜๋Š” ์ˆ˜๋ฅผ ์ฐพ๋Š”๋‹ค.
    • l์€ left๋กœ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’(sub[0]์˜ ์‹œ์ž‘์ )์„ ๊ฐ€๋ฆฌํ‚ค๊ณ , r์€ right๋กœ ๊ฐ€์žฅ ํฐ ๊ฐ’(sub[1]์˜ ๋์ )์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
    • *l + *r ์˜ ๊ฐ’์ด
      • S๋ณด๋‹ค ํฌ๋ฉด r์„ ์™ผ์ชฝ์œผ๋กœ ํ•œ ์นธ ๋‹น๊ธฐ๊ณ (--r)
      • S๋ณด๋‹ค ์ž‘์œผ๋ฉด l์„ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ํ•œ ์นธ ๋‹น๊ธฐ๊ณ (++l)
      • S์™€ ๊ฐ™์œผ๋ฉด l์€ *l ๋ณด๋‹ค ์ตœ์ดˆ๋กœ ํฐ ๊ฐ’์ธ ๊ณณ(upper_bound)์œผ๋กœ ์ด๋™ํ•˜๊ณ , r์€ *r ๋ณด๋‹ค ์ตœ์ดˆ๋กœ ์ž‘์€ ๊ฐ’์ธ ๊ณณ(lower_bound - 1)์œผ๋กœ ์ด๋™ํ•œ๋‹ค. → p0.second, p1.first
  • ๋งˆ์ง€๋ง‰์œผ๋กœ ์ฐพ๋Š” S๊ฐ€ 0์ด๋ผ๋ฉด, ๋ถ€๋ถ„์ง‘ํ•ฉ์„ ๊ตฌํ–ˆ์„ ๋‹น์‹œ ๊ณต์ง‘ํ•ฉ(0)์„ ํฌํ•จํ•˜์—ฌ ๊ตฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ณต์ง‘ํ•ฉ์„ ์ œ์™ธํ•˜๊ณ  ์ถœ๋ ฅํ•œ๋‹ค. → ans--;

 

์ฝ”๋“œ

๋ฉ”๋ชจ๋ฆฌ ์‹œ๊ฐ„
 13528 KB  292 ms
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
 
int main() {
    int n, s;
    scanf("%d%d"&n, &s);
    vector<int> seq[2], sub[2];
    for (int i = 0, num; i < n; ++i) {
        scanf("%d"&num);
        seq[i % 2].push_back(num);
    }
    for (int i = 0; i < 2++i) {
        //๋น„ํŠธ๋งˆ์Šคํฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ชจ๋“  ๋ถ€๋ถ„์ง‘ํ•ฉ ํ™•์ธ
        for (int j = 0; j < (1 << seq[i].size()); j++) {
            int sum = 0;
            for (int k = 0; k < seq[i].size(); ++k)
                if (j & (1 << k)) sum += seq[i][k];
            sub[i].push_back(sum);
        }
        sort(sub[i].begin(), sub[i].end());
    }
 
    auto l = sub[0].begin(), r = sub[1].end() - 1;
    ll ans = 0;
    while (l != sub[0].end() && r >= sub[1].begin()) {
        if (*+ *== s) {
            auto p0 = equal_range(sub[0].begin(), sub[0].end(), *l);
            auto p1 = equal_range(sub[1].begin(), sub[1].end(), *r);
            ans += (p0.second - p0.first) * (p1.second - p1.first);
            l = p0.second;
            r = p1.first;
            if (r == sub[1].begin()) break;
            --r;
        }
        else if (*+ *> s) {
            if (r == sub[1].begin()) break;
            --r;
        }
        else ++l;
    }
    if (s == 0) ans--;
    printf("%lld", ans);
    return 0;
}
cs

๋‹ค๋ฅธ ํ’€์ด(lower_bound, upper_bound)

๋ฉ”๋ชจ๋ฆฌ ์‹œ๊ฐ„
 13528 KB  324 ms
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
// num๊ณผ ๊ฐ’์ด ๊ฐ™์€ ์›์†Œ ๊ฐœ์ˆ˜ ์ฐพ๋Š” ํ•จ์ˆ˜
ll count(vector<int>& seq, int num) {
    // upper_bound(begin, end, num) -> ๊ตฌ๊ฐ„์—์„œ num๋ณด๋‹ค ํฐ ์ˆ˜๋“ค ์ค‘ ์ตœ์†Ÿ๊ฐ’
    // lower_bound(begin, end, num) -> ๊ตฌ๊ฐ„์—์„œ num๋ณด๋‹ค ์ž‘์ง€ ์•Š์€ ๊ฐ’ ์ค‘ ์ตœ์†Ÿ๊ฐ’
    return upper_bound(seq.begin(), seq.end(), num) - lower_bound(seq.begin(), seq.end(), num);
}
 
int main() {
    int n, s;
    scanf("%d%d"&n, &s);
    vector<int> seq[2], sub[2];
    for (int i = 0, num; i < n; ++i) {
        scanf("%d"&num);
        seq[i % 2].push_back(num);
    }
    for (int i = 0; i < 2++i) {
        //๋น„ํŠธ๋งˆ์Šคํฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ชจ๋“  ๋ถ€๋ถ„์ง‘ํ•ฉ ํ™•์ธ
        for (int j = (1 << seq[i].size()); j > 0; j--) {
            int sum = 0;
            for (int k = 0; k < seq[i].size(); ++k)
                if (j & (1 << k)) sum += seq[i][k];
            sub[i].push_back(sum);
        }
        sort(sub[i].begin(), sub[i].end());
    }
 
    auto l = sub[0].begin(), r = sub[1].end() - 1;
    ll ans = 0;
    while (l != sub[0].end() && r >= sub[1].begin()) {
        if (*+ *== s) {
            ans += count(sub[0], *l) * count(sub[1], *r);
            l = upper_bound(sub[0].begin(), sub[0].end(), *l);
            r = lower_bound(sub[1].begin(), sub[1].end(), *r);
            if (r == sub[1].begin()) break;
            r--;
        }
        else if (*+ *> s) {
            if (r == sub[1].begin()) break;
            --r;
        }
        else ++l;
    }
    if(s == 0) ans--;
    printf("%lld", ans);
    return 0;
}
cs

์‹œ๊ฐ„์ดˆ๊ณผ

  • lower_bound, upper_bound๋ฅผ ํ™œ์šฉํ•ด ๋ฌธ์ œ๋ฅผ ํ’€์—ˆ์„ ๋•Œ๋Š” ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋‚˜์„œ, ์œ„์˜ ์ฝ”๋“œ ์ฒ˜๋Ÿผ equal_range ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ’€์—ˆ๋‹ค.
  • ๋ญ๊ฐ€ ๋ฌธ์ œ์ธ์ง€ ์ฐพ์•„๋ณด๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ๋ฅผ ๋ณ€ํ˜•ํ•ด๊ฐ€๋ฉฐ ์ œ์ถœํ•ด๋ดค๋Š”๋ฐ ์ •๋‹ต์€ count ํ•จ์ˆ˜์— ์žˆ์—ˆ๋‹ค.
ll count(vector<int> seq, int num) {
	return upper_bound(seq.begin(), seq.end(), num) - lower_bound(seq.begin(), seq.end(), num);
}
ll count(vector<int>& seq, int num) {
    return upper_bound(seq.begin(), seq.end(), num) - lower_bound(seq.begin(), seq.end(), num);
}
  • ๋‘ ์ฝ”๋“œ์˜ ์ฐจ์ด๋Š” ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ์— ์žˆ๋‹ค.
  • 'll count(vector<int> seq, int num)'์ด ์•„๋‹ˆ๋ผ 'll count(vector<int>& seq, int num)'๋ผ๊ณ  ์ž‘์„ฑํ•ด์•ผ ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋‚˜์ง€ ์•Š๊ณ  ์ •๋‹ต์ฒ˜๋ฆฌ๊ฐ€ ๋œ๋‹ค!
  • ์ฒซ ๋ฒˆ์งธ ๊ฒฝ์šฐ์—๋Š” vector<int> seq๋กœ ๋ชจ๋“  ๋ฐฐ์—ด์˜ ๋‚ด์šฉ์ด ๋ณต์‚ฌ๊ฐ€ ๋˜์–ด ๊ณต๊ฐ„๊ณผ ์‹œ๊ฐ„์ด ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋งŒํผ ํ• ๋‹น, ํ• ์• ๊ฐ€ ๋˜๊ณ , ๋‘ ๋ฒˆ์งธ ๊ฒฝ์šฐ์—๋Š” &์—ฐ์‚ฐ์ž๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ฃผ์†Œ๊ฐ’๋งŒ ์ „๋‹ฌ๋ฐ›์•„ ํ™œ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ›จ์”ฌ ํ•ฉ๋ฆฌ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
  • ํŠนํžˆ๋‚˜ N์ด 40์ด๋ฉด ๊ทธ ์ ˆ๋ฐ˜์ด 20์ผ ๋•Œ, ๋ถ€๋ถ„์ง‘ํ•ฉ์˜ ํฌ๊ธฐ๋Š” ์ตœ๋Œ€ ์–ต์ด ๋„˜์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ์ฐจ์ด๊ฐ€ ๋” ํฐ ๊ฒƒ ๊ฐ™๋‹ค.
  • ์ด์ „๊นŒ์ง€๋Š” ํฐ ๊ฒฝ๊ฐ์‹ฌ์„ ๊ฐ–์ง€ ์•Š๊ณ  ๋‘ ๊ฐ€์ง€ ๋ชจ๋‘ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ์‚ฌ์šฉํ–ˆ๋˜ ํ„ฐ๋ผ ์ด๋ฒˆ ๋ฌธ์ œ๋กœ ์ค‘์š”์„ฑ์„ ์•Œ๊ฒŒ๋œ ๊ฒƒ ๊ฐ™๋‹ค.

๋Œ“๊ธ€