SRM455 Div1 Medium(550) ConvexHexagons
元の正三角形から小さな正三角形を切り出し、その正三角形の頂点を切り落として六角形を作ると考える。
サイズNの正三角形に含まれるサイズtの正三角形の個数は(N-t+2)(N-t+1)/2。サイズtの正三角形から上・左下・右下の切り取る幅をそれぞれu, l, rとすると、各辺に少なくとも長さ1は辺が残ることを考えて、可能な組み合わせは、1≦u≦t-2, 1≦r≦t-u-1, 1≦l≦t-max(u,r)-1。
これをそのまま書くとO(n3)で間に合わないので場合分けしてゴリゴリ計算しO(n)に落とすのが想定解法な気がするが、最初10項くらいを出力してオンライン整数列大辞典でカンニングすると、((t-2)2+1)(2(t-2)+3)/8と書けるらしい。上位陣のコードを見てみると確かにこの数式が出てくる。
using namespace std; class ConvexHexagons { public: int find( int N ); }; int ConvexHexagons::find( int N ) { long long r = 0; for ( long long t=3; t<=N; t++ ) { // 三角形の数 long long tn = (N-t+1)*(N-t+2)/2 % 1000000007; // 六角形の数 long long n = t - 2; long long hn = (n*n+1)*(2*n+3)/8 % 1000000007; r += tn * hn; r %= 1000000007; } return (int)r; }