SRM475 Div1 Medium(600) RabbitIncreasing
わからなかったので、あちこちのブログなどを参考に。剰余で計算していると、ドナドナされる番数が2才以上の番数よりも多ければ〜という比較と、偶奇の判定ができない。1年目以外は2才以上の番は子供を産むので、2才以上の番を消して、1才の番を半分にすれ良い。また、偶奇の判定は250の剰余(実際はオーバーフローに任せられる)を覚えておけば良い。なるほど。
#include <vector> #include <algorithm> using namespace std; class RabbitIncreasing { public: int getNumber( vector <int> leaving, int k ); }; int RabbitIncreasing::getNumber( vector <int> leaving, int k ) { typedef unsigned long long ull; const ull M = 1000000009; const ull M2 = 500000005; // 1/2 ull c0m = 0, c0b = 0; // 0才の番 ull c1m = 0, c1b = 0; // 1才の番 ull c2m = 0, c2b = 0; // 2才以上の番 for ( int y=1; y<=k; y++ ) { // 3月 c0m = c2m, c0b = c2b; // 7月 if ( y == 1 ) c0m++, c0b++; // 11月 if ( find( leaving.begin(), leaving.end(), y ) != leaving.end() ) { if ( y == 1 ) c0m = 0, c0b = 0; else { if ( c1b % 2 == 0 ) c1m = c1m * M2 % M; else c1m = ( c1m + M - 1 ) * M2 % M; c1b /= 2; c2m = 0, c2b = 0; } } // 12月 c2m = ( c2m + c1m ) % M, c2b += c1b; c1m = c0m, c1b = c0b; c0m = 0, c0b = 0; } return ( c0m + c1m + c2m ) % M; }