GGGCCCDDD 문제..

  • berebere86
    berebere86

    GGGCCCDDD 문제를 풀고있는데요

    문제설명에서 처럼 for문을 실제로 여러개 돌린
    아주... 느린 알고리즘과 답을 비교해봐도 일치하는것까지 확인했는데 제출하면 오답이라 나오네요.

    도대체 어떤 부분을 빼먹고 생각한건지 아무래도 모르겠어서 질문합니다ㅠㅠ

    코드가 간단하긴 하지만 방법을 설명하자면
    gcd는 1부터 n까지의 수가 나올수 있고 sum[i]에는 i가 gcd로 나올수 있는 개수를 계산합니다.

    n = 10, m = 4일때 gcd가 2를 가지려면 2의 배수들의 조합이어야하고
    따라서 2, 4, 6, 8, 10에서 5^4 = 625개가 되는데
    이때 gcd가 4, 6, 8, 10이 되는 조합과 겹치므로
    sum list를 반대로 보면서 그 조합들의 개수를 빼주게 됩니다.

    비교해본 결과 (아마도) 알고리즘은 맞는것 같은데
    빼먹은 부분이 대체 뭘까요..

    #include<stdio.h>
    #define MM 1000000007
    long ppow(int x, int a) {
        if (a == 0) return 1;
        if (a%2 > 0) return (ppow(x, a-1)*x) % MM;
        long half = ppow(x, a/2) % MM;
        return (half * half) % MM;
    }
    int main() {
        int cases;
        scanf("%d", &cases);
        while(cases--) {
            int n, m;
            scanf("%d %d", &n, &m);
    
            long sum[n+1];
            int i, j;
            for (i = 1; i <= n; i++) {
                sum[i] = ppow(n/i, m);
                sum[i] %= MM;
            }
            for (i = n/2; i > 0; i--) {
                for (j = 2; i*j <= n; j++) {
                    sum[i] -= sum[i*j];
                    sum[i] %= MM;
                    if (sum[i] <= 0) sum[i] += MM;
                }
            }
            long S = 0;
            for (i = 1; i <= n; i++) {
                S += sum[i]*i;
                S %= MM;
            }
            printf("%ld\n", S);
        }
    }
    


    10년 전
2개의 댓글이 있습니다.
  • yeonzzg
    yeonzzg

    c++은 64bit 정수 타입은 long long 아닌가요?


    10년 전 link
  • berebere86
    berebere86

    헐ㅠㅠ 그렇네요 바로 통과되네요ㅠㅠ
    항상 64bit 머신에서 코딩하니까 전혀 그 문제를 감지 못했군요..
    엉엉 정말 감사합니다!!!!!


    10년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.