# hard coding N,H(87), from STDIN(79)
g=->r=9,x{r<0?0:g[r-=1,x]-(g[r,x/=p=r==6?3:r*3+r%2+7]-x*(x+1)/2)*p};p g[10**5],g[10**9]
#g=->r=9,x{r<0?0:g[r-=1,x]-(g[r,x/=p=r==6?3:r*3+r%2+7]-x*x-x)*p};p g[eval *$<]/2
#----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0
# for general parameters(131)
#require'prime';f=->m=31,n{q=Prime.each(m).to_a;(g=->r,x{r<2?0:g[r-=1,x]-(g[r,x/=p=q[r]]-x*x-x)*p})[q.size,n]/2};p f[10**5],f[10**9]
#p f[5,20],f[5,1000],f[1000]
#----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2----+----3----+----4
# just one pair of parameters (ex. 31,10**9 etc. ) from STDIN(119)
#require'prime';eval "m,n=#{gets}q=Prime.each(m).to_a;p (g=->r,x{r<2?0:g[r-=1,x]-(g[r,x/=p=q[r]]-x*x-x)*p})[q.size,n]/2"
#----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2----+----3----+----4
__END__
○以下提出内容
【解答】
・第1問:3469796305
・第2問:347147851533059033
【方針】
奇素数列 p[0]=3, p[1]=5, …, p[9]=31, … に対し、g(r,x)=Σ{1≦k≦x| k は p[0],…,p[r]のいずれかで割り切れる} とする。
この時、
g(r+1,x)=p[r+1]*n*(n+1)/2 + g(r,x) - p[r+1]*g(r,n) ( ただし、n=floor(x/p[r+1]) )
という漸化式が成立する。
※これは、「p[r+1]の倍数」の和、「p[0]~p[r]いずれかで割り切れる数」の和を足し合わせた数値から、重複している
「p[r+1]の倍数かつp[0]~p[r]のいずれかで割り切れる数」の和を引いたものである
ここで、g(0,x)=p[0]*n*(n+1)/2 ( n=floor(x/p[0]) ) としても良いが、r=-1の分を仮想的に g(-1,x)=0 と拡張しても結果は妥当である。
よって、
g(-1,x)=0
g(r+1,x)=p[r+1]*n*(n+1)/2 + g(r,x) - p[r+1]*g(r,n) ( ただし、r≧-1, n=floor(x/p[r+1]) )
を実装することで答えを求める。
以下の通り、素数列を固定することで105文字のコードとなった。
他、素数のインデクスの代わりに、素数そのものの上限をパラメータに取る一般化バージョンでは134文字、
更にstdinからの入力をパラメータとする ( 例えば 31,10**9 ) バージョンでは120文字となり、いずれも1tweetに収めることができる。
【言語】Ruby
【コード】
# ハードコーディング(105)
g=->r,x{r<0?0:g[r-1,x]-(g[r-1,x/=p=[3,5,7,11,13,17,19,23,29,31][r]]-x*(x+1)/2)*p};p g[9,10**5],g[9,10**9]
IyBoYXJkIGNvZGluZyBOLEgoODcpLCBmcm9tIFNURElOKDc5KQogZz0tPnI9OSx4e3I8MD8wOmdbci09MSx4XS0oZ1tyLHgvPXA9cj09Nj8zOnIqMytyJTIrN10teCooeCsxKS8yKSpwfTtwIGdbMTAqKjVdLGdbMTAqKjldCiNnPS0+cj05LHh7cjwwPzA6Z1tyLT0xLHhdLShnW3IseC89cD1yPT02PzM6ciozK3IlMis3XS14KngteCkqcH07cCBnW2V2YWwgKiQ8XS8yCiMtLS0tKy0tLS0xLS0tLSstLS0tMi0tLS0rLS0tLTMtLS0tKy0tLS00LS0tLSstLS0tNS0tLS0rLS0tLTYtLS0tKy0tLS03LS0tLSstLS0tOC0tLS0rLS0tLTktLS0tKy0tLS0wCgojIGZvciBnZW5lcmFsIHBhcmFtZXRlcnMoMTMxKQojcmVxdWlyZSdwcmltZSc7Zj0tPm09MzEsbntxPVByaW1lLmVhY2gobSkudG9fYTsoZz0tPnIseHtyPDI/MDpnW3ItPTEseF0tKGdbcix4Lz1wPXFbcl1dLXgqeC14KSpwfSlbcS5zaXplLG5dLzJ9O3AgZlsxMCoqNV0sZlsxMCoqOV0KI3AgZls1LDIwXSxmWzUsMTAwMF0sZlsxMDAwXQojLS0tLSstLS0tMS0tLS0rLS0tLTItLS0tKy0tLS0zLS0tLSstLS0tNC0tLS0rLS0tLTUtLS0tKy0tLS02LS0tLSstLS0tNy0tLS0rLS0tLTgtLS0tKy0tLS05LS0tLSstLS0tMC0tLS0rLS0tLTEtLS0tKy0tLS0yLS0tLSstLS0tMy0tLS0rLS0tLTQKCiMganVzdCBvbmUgcGFpciBvZiBwYXJhbWV0ZXJzIChleC4gMzEsMTAqKjkgZXRjLiApIGZyb20gU1RESU4oMTE5KQojcmVxdWlyZSdwcmltZSc7ZXZhbCAibSxuPSN7Z2V0c31xPVByaW1lLmVhY2gobSkudG9fYTtwIChnPS0+cix4e3I8Mj8wOmdbci09MSx4XS0oZ1tyLHgvPXA9cVtyXV0teCp4LXgpKnB9KVtxLnNpemUsbl0vMiIKIy0tLS0rLS0tLTEtLS0tKy0tLS0yLS0tLSstLS0tMy0tLS0rLS0tLTQtLS0tKy0tLS01LS0tLSstLS0tNi0tLS0rLS0tLTctLS0tKy0tLS04LS0tLSstLS0tOS0tLS0rLS0tLTAtLS0tKy0tLS0xLS0tLSstLS0tMi0tLS0rLS0tLTMtLS0tKy0tLS00Cl9fRU5EX18K4peL5Lul5LiL5o+Q5Ye65YaF5a65CuOAkOino+etlOOAkQrjg7vnrKzvvJHllY/vvJozNDY5Nzk2MzA1CuODu+esrO+8kuWVj++8mjM0NzE0Nzg1MTUzMzA1OTAzMwrjgJDmlrnph53jgJEK5aWH57Sg5pWw5YiXIHBbMF09MywgcFsxXT01LCDigKYsIHBbOV09MzEsIOKApiDjgavlr77jgZfjgIFnKHIseCk9zqN7MeKJpmviiaZ4fCBrIOOBryBwWzBdLOKApixwW3Jd44Gu44GE44Ga44KM44GL44Gn5Ymy44KK5YiH44KM44KLfSDjgajjgZnjgovjgIIK44GT44Gu5pmC44CBCuOAgGcocisxLHgpPXBbcisxXSpuKihuKzEpLzIgKyBnKHIseCkgLSBwW3IrMV0qZyhyLG4pICAoIOOBn+OBoOOBl+OAgW49Zmxvb3IoeC9wW3IrMV0pICkK44Go44GE44GG5ry45YyW5byP44GM5oiQ56uL44GZ44KL44CCCuKAu+OBk+OCjOOBr+OAgeOAjHBbcisxXeOBruWAjeaVsOOAjeOBruWSjOOAgeOAjHBbMF3vvZ5wW3Jd44GE44Ga44KM44GL44Gn5Ymy44KK5YiH44KM44KL5pWw44CN44Gu5ZKM44KS6Laz44GX5ZCI44KP44Gb44Gf5pWw5YCk44GL44KJ44CB6YeN6KSH44GX44Gm44GE44KLCiAg44CMcFtyKzFd44Gu5YCN5pWw44GL44GkcFswXe+9nnBbcl3jga7jgYTjgZrjgozjgYvjgaflibLjgorliIfjgozjgovmlbDjgI3jga7lkozjgpLlvJXjgYTjgZ/jgoLjga7jgafjgYLjgosKCuOBk+OBk+OBp+OAgWcoMCx4KT1wWzBdKm4qKG4rMSkvMiAoIG49Zmxvb3IoeC9wWzBdKSApIOOBqOOBl+OBpuOCguiJr+OBhOOBjOOAgXI9LTHjga7liIbjgpLku67mg7PnmoTjgasgZygtMSx4KT0wIOOBqOaLoeW8teOBl+OBpuOCgue1kOaenOOBr+WmpeW9k+OBp+OBguOCi+OAggrjgojjgaPjgabjgIEK44CAZygtMSx4KT0wCiAgZyhyKzEseCk9cFtyKzFdKm4qKG4rMSkvMiArIGcocix4KSAtIHBbcisxXSpnKHIsbikgICgg44Gf44Gg44GX44CBcuKJpy0xLCBuPWZsb29yKHgvcFtyKzFdKSApCuOCkuWun+ijheOBmeOCi+OBk+OBqOOBp+etlOOBiOOCkuaxguOCgeOCi+OAggoK5Lul5LiL44Gu6YCa44KK44CB57Sg5pWw5YiX44KS5Zu65a6a44GZ44KL44GT44Go44GnMTA15paH5a2X44Gu44Kz44O844OJ44Go44Gq44Gj44Gf44CCCuS7luOAgee0oOaVsOOBruOCpOODs+ODh+OCr+OCueOBruS7o+OCj+OCiuOBq+OAgee0oOaVsOOBneOBruOCguOBruOBruS4iumZkOOCkuODkeODqeODoeODvOOCv+OBq+WPluOCi+S4gOiIrOWMluODkOODvOOCuOODp+ODs+OBp+OBrzEzNOaWh+Wtl+OAgQrmm7TjgatzdGRpbuOBi+OCieOBruWFpeWKm+OCkuODkeODqeODoeODvOOCv+OBqOOBmeOCiyAoIOS+i+OBiOOBsCAzMSwxMCoqOSApIOODkOODvOOCuOODp+ODs+OBp+OBrzEyMOaWh+Wtl+OBqOOBquOCiuOAgeOBhOOBmuOCjOOCgjF0d2VldOOBq+WPjuOCgeOCi+OBk+OBqOOBjOOBp+OBjeOCi+OAggoK44CQ6KiA6Kqe44CRUnVieQoK44CQ44Kz44O844OJ44CRCiMg44OP44O844OJ44Kz44O844OH44Kj44Oz44KwKDEwNSkKIGc9LT5yLHh7cjwwPzA6Z1tyLTEseF0tKGdbci0xLHgvPXA9WzMsNSw3LDExLDEzLDE3LDE5LDIzLDI5LDMxXVtyXV0teCooeCsxKS8yKSpwfTtwIGdbOSwxMCoqNV0sZ1s5LDEwKio5XQoK