Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

21-yuyu0830 #79

Merged
merged 3 commits into from
Aug 5, 2024
Merged

21-yuyu0830 #79

merged 3 commits into from
Aug 5, 2024

Conversation

yuyu0830
Copy link
Collaborator

πŸ”— 문제 링크

1의 개수 μ„ΈκΈ°

image
ν”Œλž˜ν‹°λ„˜ 가버렷!

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

2μ‹œκ°„

✨ μˆ˜λ„ μ½”λ“œ

❓ 문제

μžμ—°μˆ˜ A, Bκ°€ 주어진닀. 이 λ•Œ ν•¨μˆ˜ f(x)λ₯Ό 2μ§„μˆ˜ x의 1의 개수라고 ν–ˆμ„ λ•Œ, AλΆ€ν„° BκΉŒμ§€μ˜ 이λ₯΄λŠ” λͺ¨λ“  μžμ—°μˆ˜μ˜ f(x)의 합을 κ΅¬ν•˜μž.
image

쑰건

  • (1 ≀ A ≀ B ≀ 10^16)

❗ 풀이

image
λ…ΈνŠΈμ— 각 μžμ—°μˆ˜λ§ˆλ‹€ 0 ~ n κΉŒμ§€μ˜ 1의 개수λ₯Ό λΉΌκ³‘ν•˜κ²Œ μ μ–΄μ„œ λ΄€λŠ”λ° λ”±νžˆ 연관성을 찾지 λͺ»ν–ˆλ‹€.. 있긴 ν–ˆλŠ”λ° 생각보닀 접근이 μ–΄λ €μ› λ‹€.


ν’€μ΄λŠ” 2개의 μŠ€ν…μœΌλ‘œ λ‚˜λˆŒ 수 μžˆλ‹€.

1️⃣ 첫번째 단계

2μ§„μˆ˜λ‘œ 봀을 λ•Œ 각 자리수 λ³„λ‘œ λ‚˜μ˜¬ 수 μžˆλŠ” 1의 κ°œμˆ˜λŠ” μ•„λž˜μ™€ κ°™λ‹€.
image

μ—¬κΈ°μ„œ 쑰금 μ‚΄νŽ΄λ³΄λ©΄ λ‹€μŒκ³Ό 같은 νŠΉμ§•μ΄ μžˆλ‹€.

image

(2 ^ n) - 1 κΉŒμ§€μ˜ 경우의 μˆ˜λŠ” 2 ^ (n - 1) - 1 κΉŒμ§€μ˜ 경우의 μˆ˜κ°€ ν•œλ²ˆ λ°˜λ³΅λœλ‹€. 여기에 맨 μ•žμžλ¦¬ 1이 ν•˜λ‚˜ 더 λΆ™κΈ° λ•Œλ¬Έμ— n의 자리 2μ§„μˆ˜μ˜ 개수 만큼 1이 더 생긴닀.

즉 (2 ^ n) - 1 인 2μ§„μˆ˜μ˜ 1의 개수 μ•„λž˜μ˜ μš”μ†Œλ“€μ˜ 합이 λœλ‹€.

  • 1λΆ€ν„° 2 ^ (n - 1) - 1 κΉŒμ§€μ˜ 2μ§„μˆ˜μ˜ 1의 개수 (1 ~ 2 ^ (n - 1) - 1)
  • 2 ^ (n - 1) λΆ€ν„° 2 ^ n - 1 κΉŒμ§€μ˜ 2μ§„μˆ˜μ˜ 1의 개수
  • 2 ^ n 의 1의 개수 (항상 1개)

κ·Έλž˜μ„œ 2의 n제곱인 2μ§„μˆ˜μ˜ 1의 κ°œμˆ˜λŠ” n - 1번째 자리수 2μ§„μˆ˜μ˜ 1의 개수 * 2 와 ν•΄λ‹Ή 경우의 수의 개수, 즉 2^(n - 1)의 ν•© μ΄λΌλŠ” 것을 μ•Œ 수 μžˆμ—ˆλ‹€.

이λ₯Ό 톡해 미리 각 자리수 별 1의 개수λ₯Ό 미리 ꡬ해 μ €μž₯ν•΄λ‘μž

// ll : long long int
ll arr[10000] = {0, };
ll a, b, tmp = 1; cin >> a >> b;
int cnt = 1;

// bκΉŒμ§€ arr λ°°μ—΄ λˆ„μ ν•© μ—°μ‚°
while (b > tmp) {
    arr[cnt] = (arr[cnt - 1] * 2) + tmp;
    tmp *= 2; cnt++;
}

2️⃣ λ‘λ²ˆμ§Έ 단계

이제 2의 nμ œκ³±μ€ μ•Œμ•˜λŠ”λ° 쀑간에 μžˆλŠ” 1듀은 μ–΄λ–»κ²Œ μ²˜λ¦¬ν• κΉŒ?

μœ„μ™€ λΉ„μŠ·ν•œ 원리인데
10100 의 경우 1λΆ€ν„° 1111 κΉŒμ§€μ˜ 1의 개수 + 10000 ~ 10100 κΉŒμ§€μ˜ 1의 개수둜 λ‚˜λˆŒ 수 μžˆλ‹€. 10000 ~ 10100 의 κ°œμˆ˜λŠ” 1 ~ 100 κΉŒμ§€μ˜ 1의 κ°œμˆ˜μ— 1 ~ 100 κΉŒμ§€μ˜ 2μ§„μˆ˜μ˜ 개수만큼 λ”ν•˜λ©΄ λœλ‹€.

image

10100 의 κ²½μš°μ—λŠ” μ„ ν–‰ν•œ 1이 μ΅œλŒ€ 1개기 λ•Œλ¬Έμ— 1~100 κΉŒμ§€μ˜ 1의 개수 + (n자리 2μ§„μˆ˜μ˜ 개수 * 1) 만큼 λ”ν•˜λ©΄ λ˜μ§€λ§Œ, 110100110 κ³Ό 같이 1이 λ§Žμ•„μ§€λŠ” κ²½μš°μ—λŠ” μ•žμ—μ„œλΆ€ν„° 탐색해 1을 λ§Œλ‚  λ•Œ λ§ˆλ‹€ 1 ~ 2 ^ n κΉŒμ§€μ˜ 1의 개수 + (n자리 2μ§„μˆ˜μ˜ 개수 * μ„ ν–‰ν•œ 1의 개수) κΉŒμ§€μ˜ 2μ§„μˆ˜μ˜ 개수` λ₯Ό λ”ν•˜λ©΄ λœλ‹€.


λ¬Έμ œκ°€ μ›ν•˜λŠ”κ²Œ 0 ~ n κΉŒμ§€κ°€ μ•„λ‹ˆλΌ a ~ bκΉŒμ§€κΈ° λ•Œλ¬Έμ— `0 ~ a κΉŒμ§€μ˜ 1의 개수`, `0 ~ b κΉŒμ§€μ˜ 1의 개수` λ₯Ό ꡬ해 차이λ₯Ό κ΅¬ν•˜λ©΄ λœλ‹€.

같은 숫자일 경우λ₯Ό λŒ€λΉ„ν•΄ 0 ~ b κΉŒμ§€μ˜ 1의 개수 - 0 ~ a - 1 κΉŒμ§€μ˜ 1의 개수 + a의 1의 개수 둜 κ΅¬ν–ˆλ‹€.

#include <iostream>
#include <math.h>

using namespace std;

typedef unsigned long long int ll;

ll arr[10000] = {0, };
int cnt = 1;

// 0 ~ t κΉŒμ§€μ˜ 1의 개수λ₯Ό λ°˜ν™˜
ll f(ll t) {
    int ptLog = cnt, tmp = 0;
    ll pt = pow(2, ptLog - 1), ans = 0;

    while (pt) {
        if (t & pt) {
            ans += arr[ptLog - 1] + 1;
            ans += pt * tmp++;
        }
        pt >>= 1;
        ptLog--;
    }

    return ans;
}

int main() {
    ll a, b, tmp = 1; cin >> a >> b;

    // bκΉŒμ§€ arr λ°°μ—΄ λˆ„μ ν•© μ—°μ‚°
    while (b > tmp) {
        arr[cnt] = (arr[cnt - 1] * 2) + tmp;
        tmp *= 2; cnt++;
    }

    ll ZeroToAVal = f(a); // 0 ~ a - 1 κΉŒμ§€μ˜ 1의 개수
    ll bVal = f(b);       // 0 ~ b κΉŒμ§€μ˜ 1의 개수
    ll aVal = 0;          // a 의 1의 개수
    
    ll pt = pow(2, cnt);
    while (pt) {
        if (a & pt) aVal++;
        pt >>= 1;
    }

    printf("%lld\n", bVal - ZeroToAVal + aVal);
}

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

μ—­μ‹œ μˆ˜ν•™ 문제 μž¬λ°Œλ„€μš” γ…Žγ…Ž

Copy link
Collaborator

@InSange InSange left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

λˆ„μ ν•©κ³Ό dp ν˜•μ‹μœΌλ‘œ 이전 것을 μ €μž₯ν•΄λ‚˜κ°€λŠ” μ‹μœΌλ‘œ ν•œλ²ˆ ν•΄λ³΄μ•˜μ§€λ§Œ λ©”λͺ¨λ¦¬ 초과.. 10^16을 λ‹΄κΈ°μ—λŠ” μ—­λΆ€μ‘±μ΄κ΅°μš”.. λ‹€μ‹œ ν•œλ²ˆ 풀어봐야 κ² μŠ΅λ‹ˆλ‹€. μˆ˜ν•™μ€ μ—­μ‹œ μ–΄λ €μ›Œ

Copy link
Collaborator

@seongwon030 seongwon030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 μˆ˜ν•™μ„ μ°Έ μ’‹μ•„ν•˜λŠ”λ°μš”. μˆ˜ν•™λ¬Έμ œλ₯Ό ν’€ λ•ŒλŠ” νŽœμ„ λ¨Όμ € λ“€μ–΄μ•Ό ν•˜λ”λΌκ³ μš”. 적어놓고 μ—¬λŸ¬λ²ˆ 봐야 보인닀고 ν•΄μ•Όν•˜λ‚˜.. λˆ„μ ν•©κΈ΄ ν•˜μ§€λ§Œ 2μ§„μˆ˜μ—μ„œ 1이 λ‚˜μ˜€λŠ” νŒ¨ν„΄μ„ 찾지 λͺ»ν•˜λ©΄ μ €μž₯ν•  수 μ—†λŠ” λ¬Έμ œκ΅°μš”. 이런 λ¬Έμ œμ—μ„  νŒ¨ν„΄μ„ μ•Œμ•„λ‚΄λŠ”κ²Œ 급선무인 것 κ°™μŠ΅λ‹ˆλ‹€. 풀이 잘 보고 κ°‘λ‹ˆλ‹€ !

@yuyu0830 yuyu0830 merged commit 88f6b71 into main Aug 5, 2024
@yuyu0830 yuyu0830 deleted the 21-yuyu0830 branch August 5, 2024 06:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants