DELETED SRM/548-U/1A.cpp Index: SRM/548-U/1A.cpp ================================================================== --- SRM/548-U/1A.cpp +++ SRM/548-U/1A.cpp @@ -1,97 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; -typedef long long LL; -typedef long double LD; -typedef complex CMP; - -class KingdomAndTrees { public: - int minLevel(vector heights) - { - // (L,R] - int L = -1; - int R = 1000000000; - while(R-L>1) - { - int C = (L+R)/2; - (possible(C,heights) ? R : L) = C; - } - return R; - } - - bool possible(int C, const vector& h) - { - int last = max(1, h[0]-C); - for(int i=1; i -double start_time; string timer() - { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } -template ostream& operator<<(ostream& os, const vector& v) - { os << "{ "; - for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) - os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } -void verify_case(const int& Expected, const int& Received) { - bool ok = (Expected == Received); - if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; - cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } -#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); -#define END verify_case(_, KingdomAndTrees().minLevel(heights));} -int main(){ - -CASE(0) - int heights_[] = {9, 5, 11}; - vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); - int _ = 3; -END -CASE(1) - int heights_[] = {5, 8}; - vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); - int _ = 0; -END -CASE(2) - int heights_[] = {1, 1, 1, 1, 1}; - vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); - int _ = 4; -END -CASE(3) - int heights_[] = {548, 47, 58, 250, 2012}; - vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); - int _ = 251; -END -CASE(4) - int heights_[] = {337994619,837714986,7014426,516695490,268514071,590654553,940024470,79308071,891444369,231310251,172567010,283491054,951215936,92716118,911004789,896372476,617116292,874491895,120052194,635772188,938392572,466867891,418351197,278475278,635224368,38779964,762367612,370214557,20108108,314281202,644947239,868648377,617056931,542328796,280916141,281585869,895175595,529854516,862330692,733665485,173060292,579136324,401396401,303236137,161627936,410922706,172892990,840336279,848958999,849348801}; - vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); - int _ = -1; -END -CASE(5) - int heights_[] = {1000000000,1}; - vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); - int _ = 500000000; -END - -} -// END CUT HERE DELETED SRM/548-U/1B.cpp Index: SRM/548-U/1B.cpp ================================================================== --- SRM/548-U/1B.cpp +++ SRM/548-U/1B.cpp @@ -1,199 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; -typedef long long LL; -typedef long double LD; -typedef complex CMP; - -template -struct DP3 -{ - int N1, N2, N3; - vector data; - DP3(int N1, int N2, int N3, const T& t = T()) - : N1(N1), N2(N2), N3(N3), data(N1*N2*N3, t) { assert(data.size()*sizeof(T)<(1<<26)); } - T& operator()(int i1, int i2, int i3) - { return data[ ((i1*N2)+i2)*N3+i3 ]; } - void swap(DP3& rhs) - { data.swap(rhs.data); } -}; - -struct cmp { - int N; - cmp(int N):N(N){} - bool operator()(int a, int b) const - { - if( abs(2*a - N*N) != abs(2*b - N*N) ) - return abs(2*a - N*N) < abs(2*b - N*N); - return a < b; - } -}; -class KingdomAndDice { public: - double newFairness(vector firstDie, vector secondDie, int X) - { - int N = firstDie.size(); - sort(secondDie.begin(), secondDie.end()); - - vector choice; - { - choice.push_back(N); - for(int i=0; i+1& choice, int K) - { - DP3 dp(N+1, K+1, N*N+1); - for(int i=0; i<=N; ++i) - for(int p=0; p<=K; ++p) - for(int sum=0; sum<=N*N; ++sum) - { - if(i==0) - { - dp(i,p,sum) = (sum==base && p<=choice[i]); - } - else - { - bool b = false; - for(int z=0; z<=p && z<=choice[i]; ++z) - if(sum>=i*z) - b = b | dp(i-1,p-z,sum-i*z); - dp(i,p,sum) = b; - } - } - - vector cand; - for(int sum=0; sum<=N*N; ++sum) - if( dp(N,K,sum) ) - cand.push_back( sum ); - return *min_element(cand.begin(), cand.end(), cmp(N)) / double(N*N); - } -}; - -// BEGIN CUT HERE -#include -double start_time; string timer() - { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } -template ostream& operator<<(ostream& os, const vector& v) - { os << "{ "; - for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) - os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } -void verify_case(const double& Expected, const double& Received) { - bool ok = (abs(Expected - Received) < 1e-9); - if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; - cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } -#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); -#define END verify_case(_, KingdomAndDice().newFairness(firstDie, secondDie, X));} -int main(){ - -CASE(0) - int firstDie_[] = {0, 2, 7, 0}; - vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); - int secondDie_[] = {6, 3, 8, 10}; - vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); - int X = 12; - double _ = 0.4375; -END -CASE(1) - int firstDie_[] = {0, 2, 7, 0}; - vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); - int secondDie_[] = {6, 3, 8, 10}; - vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); - int X = 10; - double _ = 0.375; -END -CASE(2) - int firstDie_[] = {0, 0}; - vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); - int secondDie_[] = {5, 8}; - vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); - int X = 47; - double _ = 0.5; -END -CASE(3) - int firstDie_[] = {19, 50, 4}; - vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); - int secondDie_[] = {26, 100, 37}; - vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); - int X = 1000; - double _ = 0.2222222222222222; -END -CASE(4) - int firstDie_[] = {6371, 0, 6256, 1852, 0, 0, 6317, 3004, 5218, 9012}; - vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); - int secondDie_[] = {1557, 6318, 1560, 4519, 2012, 6316, 6315, 1559, 8215, 1561}; - vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); - int X = 10000; - double _ = 0.49; -END -CASE(5) - int firstDie_[] = {278130165,933636493,607327308,19369203,439158229,445295066,370731340,551180273,163280323,359800317,834663837,108871632,362106962,921853660,145507840,284869553,246938492,379648759,956330140,525562675,251028940,270135098,862786589,513909283,412651940,499422899,724171306,922270222,938213346,61418124,248820926,891527589,812074952,155495258,23280465,761818758,328244247,975585791,108105856,414583437,424242761,168720992,585728188,0,0,0,0,0,0,0}; - vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); - int secondDie_[] = {475017760,773630717,985005264,963668637,320647204,665487259,585555327,272107932,203172682,57845645,311126817,496577583,834654861,77335024,405827438,231342594,943378345,971851607,455697802,119475931,551079372,838525393,192593102,990828850,382044077,590561977,229071016,962163538,621629435,727621063,109926457,152882146,9199017,615779540,160320904,216276208,675743894,414050471,126645085,238141513,151262148,280509327,923103663,125699296,790073355,738597671,864455279,384833125,510401421,219630179}; - vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); - int X = 1000000000; - double _ = 0.5; -END -CASE(6) - int firstDie_[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); - int secondDie_[] = {475017760,773630717,985005264,963668637,320647204,665487259,585555327,272107932,203172682,57845645,311126817,496577583,834654861,77335024,405827438,231342594,943378345,971851607,455697802,119475931,551079372,838525393,192593102,990828850,382044077,590561977,229071016,962163538,621629435,727621063,109926457,152882146,9199017,615779540,160320904,216276208,675743894,414050471,126645085,238141513,151262148,280509327,923103663,125699296,790073355,738597671,864455279,384833125,510401421,219630179}; - vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); - int X = 1000000000; - double _ = 0.5; -END -CASE(6) - int firstDie_[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); - int secondDie_[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50}; - vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); - int X = 100; - double _ = 0.5; -END -CASE(7) -int firstDie_[] = {0,0}; - vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); - int secondDie_[] = {1,2}; - vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); - int X = 4; - double _ = 1; -END - -} -// END CUT HERE ADDED SRM/548/1A.cpp Index: SRM/548/1A.cpp ================================================================== --- SRM/548/1A.cpp +++ SRM/548/1A.cpp @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef long double LD; +typedef complex CMP; + +class KingdomAndTrees { public: + int minLevel(vector heights) + { + // (L,R] + int L = -1; + int R = 1000000000; + while(R-L>1) + { + int C = (L+R)/2; + (possible(C,heights) ? R : L) = C; + } + return R; + } + + bool possible(int C, const vector& h) + { + int last = max(1, h[0]-C); + for(int i=1; i +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template ostream& operator<<(ostream& os, const vector& v) + { os << "{ "; + for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) + os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } +void verify_case(const int& Expected, const int& Received) { + bool ok = (Expected == Received); + if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; + cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } +#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); +#define END verify_case(_, KingdomAndTrees().minLevel(heights));} +int main(){ + +CASE(0) + int heights_[] = {9, 5, 11}; + vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); + int _ = 3; +END +CASE(1) + int heights_[] = {5, 8}; + vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); + int _ = 0; +END +CASE(2) + int heights_[] = {1, 1, 1, 1, 1}; + vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); + int _ = 4; +END +CASE(3) + int heights_[] = {548, 47, 58, 250, 2012}; + vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); + int _ = 251; +END +CASE(4) + int heights_[] = {337994619,837714986,7014426,516695490,268514071,590654553,940024470,79308071,891444369,231310251,172567010,283491054,951215936,92716118,911004789,896372476,617116292,874491895,120052194,635772188,938392572,466867891,418351197,278475278,635224368,38779964,762367612,370214557,20108108,314281202,644947239,868648377,617056931,542328796,280916141,281585869,895175595,529854516,862330692,733665485,173060292,579136324,401396401,303236137,161627936,410922706,172892990,840336279,848958999,849348801}; + vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); + int _ = -1; +END +CASE(5) + int heights_[] = {1000000000,1}; + vector heights(heights_, heights_+sizeof(heights_)/sizeof(*heights_)); + int _ = 500000000; +END + +} +// END CUT HERE ADDED SRM/548/1B.cpp Index: SRM/548/1B.cpp ================================================================== --- SRM/548/1B.cpp +++ SRM/548/1B.cpp @@ -0,0 +1,199 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef long double LD; +typedef complex CMP; + +template +struct DP3 +{ + int N1, N2, N3; + vector data; + DP3(int N1, int N2, int N3, const T& t = T()) + : N1(N1), N2(N2), N3(N3), data(N1*N2*N3, t) { assert(data.size()*sizeof(T)<(1<<26)); } + T& operator()(int i1, int i2, int i3) + { return data[ ((i1*N2)+i2)*N3+i3 ]; } + void swap(DP3& rhs) + { data.swap(rhs.data); } +}; + +struct cmp { + int N; + cmp(int N):N(N){} + bool operator()(int a, int b) const + { + if( abs(2*a - N*N) != abs(2*b - N*N) ) + return abs(2*a - N*N) < abs(2*b - N*N); + return a < b; + } +}; +class KingdomAndDice { public: + double newFairness(vector firstDie, vector secondDie, int X) + { + int N = firstDie.size(); + sort(secondDie.begin(), secondDie.end()); + + vector choice; + { + choice.push_back(N); + for(int i=0; i+1& choice, int K) + { + DP3 dp(N+1, K+1, N*N+1); + for(int i=0; i<=N; ++i) + for(int p=0; p<=K; ++p) + for(int sum=0; sum<=N*N; ++sum) + { + if(i==0) + { + dp(i,p,sum) = (sum==base && p<=choice[i]); + } + else + { + bool b = false; + for(int z=0; z<=p && z<=choice[i]; ++z) + if(sum>=i*z) + b = b | dp(i-1,p-z,sum-i*z); + dp(i,p,sum) = b; + } + } + + vector cand; + for(int sum=0; sum<=N*N; ++sum) + if( dp(N,K,sum) ) + cand.push_back( sum ); + return *min_element(cand.begin(), cand.end(), cmp(N)) / double(N*N); + } +}; + +// BEGIN CUT HERE +#include +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template ostream& operator<<(ostream& os, const vector& v) + { os << "{ "; + for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) + os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } +void verify_case(const double& Expected, const double& Received) { + bool ok = (abs(Expected - Received) < 1e-9); + if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; + cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } +#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); +#define END verify_case(_, KingdomAndDice().newFairness(firstDie, secondDie, X));} +int main(){ + +CASE(0) + int firstDie_[] = {0, 2, 7, 0}; + vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); + int secondDie_[] = {6, 3, 8, 10}; + vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); + int X = 12; + double _ = 0.4375; +END +CASE(1) + int firstDie_[] = {0, 2, 7, 0}; + vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); + int secondDie_[] = {6, 3, 8, 10}; + vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); + int X = 10; + double _ = 0.375; +END +CASE(2) + int firstDie_[] = {0, 0}; + vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); + int secondDie_[] = {5, 8}; + vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); + int X = 47; + double _ = 0.5; +END +CASE(3) + int firstDie_[] = {19, 50, 4}; + vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); + int secondDie_[] = {26, 100, 37}; + vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); + int X = 1000; + double _ = 0.2222222222222222; +END +CASE(4) + int firstDie_[] = {6371, 0, 6256, 1852, 0, 0, 6317, 3004, 5218, 9012}; + vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); + int secondDie_[] = {1557, 6318, 1560, 4519, 2012, 6316, 6315, 1559, 8215, 1561}; + vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); + int X = 10000; + double _ = 0.49; +END +CASE(5) + int firstDie_[] = {278130165,933636493,607327308,19369203,439158229,445295066,370731340,551180273,163280323,359800317,834663837,108871632,362106962,921853660,145507840,284869553,246938492,379648759,956330140,525562675,251028940,270135098,862786589,513909283,412651940,499422899,724171306,922270222,938213346,61418124,248820926,891527589,812074952,155495258,23280465,761818758,328244247,975585791,108105856,414583437,424242761,168720992,585728188,0,0,0,0,0,0,0}; + vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); + int secondDie_[] = {475017760,773630717,985005264,963668637,320647204,665487259,585555327,272107932,203172682,57845645,311126817,496577583,834654861,77335024,405827438,231342594,943378345,971851607,455697802,119475931,551079372,838525393,192593102,990828850,382044077,590561977,229071016,962163538,621629435,727621063,109926457,152882146,9199017,615779540,160320904,216276208,675743894,414050471,126645085,238141513,151262148,280509327,923103663,125699296,790073355,738597671,864455279,384833125,510401421,219630179}; + vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); + int X = 1000000000; + double _ = 0.5; +END +CASE(6) + int firstDie_[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); + int secondDie_[] = {475017760,773630717,985005264,963668637,320647204,665487259,585555327,272107932,203172682,57845645,311126817,496577583,834654861,77335024,405827438,231342594,943378345,971851607,455697802,119475931,551079372,838525393,192593102,990828850,382044077,590561977,229071016,962163538,621629435,727621063,109926457,152882146,9199017,615779540,160320904,216276208,675743894,414050471,126645085,238141513,151262148,280509327,923103663,125699296,790073355,738597671,864455279,384833125,510401421,219630179}; + vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); + int X = 1000000000; + double _ = 0.5; +END +CASE(6) + int firstDie_[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); + int secondDie_[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50}; + vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); + int X = 100; + double _ = 0.5; +END +CASE(7) +int firstDie_[] = {0,0}; + vector firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); + int secondDie_[] = {1,2}; + vector secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); + int X = 4; + double _ = 1; +END + +} +// END CUT HERE ADDED SRM/548/1C.cpp Index: SRM/548/1C.cpp ================================================================== --- SRM/548/1C.cpp +++ SRM/548/1C.cpp @@ -0,0 +1,160 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef long double LD; +typedef complex CMP; + +static const int MODVAL = 1000000007; +struct mint +{ + int val; + mint():val(0){} + mint(int x):val(x%MODVAL) {} + mint(size_t x):val(x%MODVAL) {} + mint(LL x):val(x%MODVAL) {} +}; +mint& operator+=(mint& x, mint y) { return x = x.val+y.val; } +mint& operator-=(mint& x, mint y) { return x = x.val-y.val+MODVAL; } +mint& operator*=(mint& x, mint y) { return x = LL(x.val)*y.val; } +mint operator+(mint x, mint y) { return x+=y; } +mint operator-(mint x, mint y) { return x-=y; } +mint operator*(mint x, mint y) { return x*=y; } +vector< vector > CP_; +mint C(LL n, LL k) { + while( CP_.size() <= n ) { + int nn = CP_.size(); + CP_.push_back(vector(nn+1,1)); + for(int kk=1; kk, mint> memo; + mint zero(int N, int K) + { + pair key(N, K); + if(memo.count(key)) + return memo[key]; + + mint sum = zero_may_be_disconnected(N, K); + for(int NA=1; NA<=N-1; ++NA) + for(int KA=0; KA<=K; ++KA) + sum -= C(N-1,NA-1)*zero(NA,KA)*zero_may_be_disconnected(N-NA, K-KA); + return memo[key] = sum; + } + + mint one(int N, int K) + { + mint sum = zero(N-1,K-2)*C(N-1,2); + for(int NA=1; NA<=N-2; ++NA) + for(int KA=0; KA<=K-2; ++KA) + sum += C(N-2,NA-1)*zero(NA,KA)*NA*(N-1-NA)*zero(N-1-NA,K-2-KA); + return sum; + } + + mint two(int N, int K) + { + mint sum = one(N-1,K-2)*C(N-2,2); + for(int NA=1; NA<=N-2; ++NA) + for(int KA=0; KA<=K-2; ++KA) + sum += C(N-2,NA-1)*one(NA,KA)*(NA-1)*(N-1-NA)*zero(N-1-NA,K-2-KA); + --N, --K; + sum += zero(N-1,K-2)*(N-1)*(N-1); + for(int NA=1; NA<=N-2; ++NA) + for(int KA=0; KA<=K-2; ++KA) + sum += C(N-1,NA)*zero(NA,KA)*NA*(N-1-NA)*zero(N-1-NA,K-2-KA); + return sum; + } +}; + +// BEGIN CUT HERE +#include +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template ostream& operator<<(ostream& os, const vector& v) + { os << "{ "; + for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) + os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } +void verify_case(const int& Expected, const int& Received) { + bool ok = (Expected == Received); + if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; + cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } +#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); +#define END verify_case(_, KingdomAndCities().howMany(N, M, K));} +int main(){ + +CASE(0) + int N = 3; + int M = 0; + int K = 3; + int _ = 1; +END +CASE(1) + int N = 4; + int M = 1; + int K = 4; + int _ = 9; +END +CASE(2) + int N = 5; + int M = 2; + int K = 11; + int _ = 0; +END +CASE(3) + int N = 5; + int M = 0; + int K = 8; + int _ = 45; +END +CASE(4) + int N = 10; + int M = 2; + int K = 20; + int _ = 150810825; +END +CASE(5) + int N = 3; + int M = 2; + int K = 3; + int _ = 1; +END +/* +CASE(6) + int N = ; + int M = ; + int K = ; + int _ = ; +END +*/ +} +// END CUT HERE