1026 - Hedro's Hexahedron

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1026&lang=jp

解法

はてなダイアリーで書くのが非常に面倒だったのでパワポで書いた

図のようにx軸y軸を取り、x軸とy軸に液体が接している時を考える
青線が液体の表面に対応している


ということで、結局 xが[1,N/2]のとき 液体に浸かるのは y <= N/2x の部分
あとは対称性を考えながら重複に注意してO(sqrt(N))で数え上げる
自分はサイド部分(の半分)と隅部分に分けて考えた

ソース

#include <cstdio>
using namespace std;

typedef long long ll;

int main() {
  ll n;
  while(scanf("%lld",&n),n) {
    ll corner = 0;
    while(corner*corner<n/2) ++corner; // sqrt(n/2)以上の最小の整数が隅部分の辺の長さ
    ll side = n/2;                     // サイドの半分
    for (ll i=1; i*i<n/2; ++i) side += (n/2+i-1)/i; // n/2/i以上の最小の整数を足す
    side -= corner*corner;                          // 隅部分の重複を取り除く
    ll ans = side*8+corner*corner*4;                // これで表面
    ans *= 2;                                       // 裏面
    ans += n*2*4;                                   // 側面を足す
    printf("%lld\n",ans);
  }
}