Snippets

cia_rana 「ディビジョン・サム」問題

Created by cia_rana last modified
package main
import (
    "fmt"
    "sync"
)

const D = 1000003

func main() {
    var n int
    fmt.Scan(&n)
    
    divChan := make(chan int)
    go func(n int, divChan chan int) {
        wg := new(sync.WaitGroup)
        for i := 1; i <= n; i++ {
            wg.Add(1)
            go func(m int) {
                defer wg.Done()
                for m % 2 == 0 {
                    m /= 2
                    divChan <- 2
                }
                for d := 3; d * d <= m; d += 2 {
                    for m % d == 0 {
                        m /= d
                        divChan <- d
                    }
                }
                if m > 1 {
                    divChan <- m
                }
            }(i)
        }
        wg.Wait()
        close(divChan)
    }(n, divChan)
    divMap := make(map[int]int)
    for d := range divChan {
        divMap[d]++
    }
    
    gsChan := make(chan int)
    go func(divMap map[int]int, gsChan chan int) {
        wg := new(sync.WaitGroup)
        for d, e := range divMap {
            wg.Add(1)
            go func(n, m, d int) {
                defer wg.Done()
                prd := uint64(1)
                pow := uint64(n)
                div := uint64(D * (d - 1))
                for m > 0 {
                    if m & 1 == 1 {
                        prd = prd * pow % div
                    }
                    pow = pow * pow % div
                    m >>= 1
                }
                gsChan <- int((prd - 1) / uint64(d - 1))
            }(d, n * e + 1, d)
        }
        wg.Wait()
        close(gsChan)
    }(divMap, gsChan)
    sum := 1
    for gs := range gsChan {
        sum = int(uint64(sum) * uint64(gs) % D)
    }
    
    fmt.Println(sum)
}
package main
import (
    "fmt"
    "sync"
)

const D = 1000003

func GeneratePrime(out chan <- int) {
    ch1 := make(chan int)
    go func(ch chan <- int) {
        ch <- 2
        for i := 3; ; i += 2 {
            ch <- i
        }
    }(ch1)
    
    for {
        prime := <- ch1
        if prime > 1100 {
            return
        }
        out <- prime
        ch2 := make(chan int)
        go func(in <- chan int, out chan <- int, prime int) {
            for {
                primeCandidate := <- in
                if primeCandidate % prime != 0 {
                    out <- primeCandidate
                }
            }
        }(ch1, ch2, prime)
        ch1 = ch2
    }
}

func main() {
    var n int
    fmt.Scan(&n)
    
    primeChan := make(chan int)
    go GeneratePrime(primeChan)
    
    gsChan := make(chan int)
    go func() {
        wg := new(sync.WaitGroup)
        for prime := range primeChan {
            if prime > n {
                break
            }
            
            wg.Add(1)
            go func(prime int, out chan <- int) {
                defer wg.Done()
                
                sum := 0
                {
                    m := n
                    for m > 0 {
                        m /= prime
                        sum += m
                    }
                }
                {
                    prd := uint64(1)
                    pow := uint64(prime)
                    div := uint64(D * (prime - 1))
                    m := n * sum + 1
                    for m > 0 {
                        if m & 1 == 1 {
                            prd = prd * pow % div
                        }
                        pow = pow * pow % div
                        m >>= 1
                    }
                    out <- int((prd - 1) / uint64(prime - 1))
                }
            }(prime, gsChan)
        }
        wg.Wait()
        close(gsChan)
    }()
    
    sum := 1
    for gs := range gsChan {
        sum = int(uint64(sum) * uint64(gs) % D)
    }
    
    fmt.Println(sum)
}
require 'prime'

D = 1_000_003

def calc_pow_with_mod(n, m, div)
  prd = 1
  pow = n
  while m > 0
    prd = (prd * pow) % div if m.odd?
    pow = (pow * pow) % div
    m /= 2
  end
  prd
end

n = gets.to_i

p Prime.each(n).reduce(Hash.new(0)){|divNum, prime|
  m = n
  while m > 0
    divNum[prime] += m /= prime
  end
  divNum
}.reduce(1){|prd, (d, e)|
  prd * (calc_pow_with_mod(d, n * e + 1, D * (d - 1)) - 1) / (d - 1) % D
}

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.