96fdfab500 2011-03-20 kinaba: #include <iostream> 96fdfab500 2011-03-20 kinaba: #include <sstream> 96fdfab500 2011-03-20 kinaba: #include <iomanip> 96fdfab500 2011-03-20 kinaba: #include <vector> 96fdfab500 2011-03-20 kinaba: #include <string> 96fdfab500 2011-03-20 kinaba: #include <map> 96fdfab500 2011-03-20 kinaba: #include <set> 96fdfab500 2011-03-20 kinaba: #include <algorithm> 96fdfab500 2011-03-20 kinaba: #include <numeric> 96fdfab500 2011-03-20 kinaba: #include <iterator> 96fdfab500 2011-03-20 kinaba: #include <functional> 96fdfab500 2011-03-20 kinaba: #include <complex> 96fdfab500 2011-03-20 kinaba: #include <queue> 96fdfab500 2011-03-20 kinaba: #include <stack> 96fdfab500 2011-03-20 kinaba: #include <cmath> 96fdfab500 2011-03-20 kinaba: #include <cassert> 96fdfab500 2011-03-20 kinaba: #include <cstring> 96fdfab500 2011-03-20 kinaba: using namespace std; 96fdfab500 2011-03-20 kinaba: typedef long long LL; 96fdfab500 2011-03-20 kinaba: typedef complex<double> CMP; 96fdfab500 2011-03-20 kinaba: 96fdfab500 2011-03-20 kinaba: static const int MODVAL = 500500573; 96fdfab500 2011-03-20 kinaba: struct mint 96fdfab500 2011-03-20 kinaba: { 96fdfab500 2011-03-20 kinaba: int val; 96fdfab500 2011-03-20 kinaba: mint():val(0){} 96fdfab500 2011-03-20 kinaba: mint(int x):val(x%MODVAL) {} 96fdfab500 2011-03-20 kinaba: mint(LL x):val(x%MODVAL) {} 96fdfab500 2011-03-20 kinaba: }; 96fdfab500 2011-03-20 kinaba: mint operator+(mint x, mint y) { return x.val+y.val; } 96fdfab500 2011-03-20 kinaba: mint operator-(mint x, mint y) { return x.val-y.val+MODVAL; } 96fdfab500 2011-03-20 kinaba: mint operator*(mint x, mint y) { return LL(x.val)*y.val; } 96fdfab500 2011-03-20 kinaba: mint POW(mint x, int e) { 96fdfab500 2011-03-20 kinaba: mint v = 1; 96fdfab500 2011-03-20 kinaba: for(;e;x=x*x,e>>=1) 96fdfab500 2011-03-20 kinaba: if(e&1) 96fdfab500 2011-03-20 kinaba: v=v*x; 96fdfab500 2011-03-20 kinaba: return v; 96fdfab500 2011-03-20 kinaba: } 96fdfab500 2011-03-20 kinaba: mint operator/(mint x, mint y) { return x * POW(y, MODVAL-2); } 96fdfab500 2011-03-20 kinaba: 96fdfab500 2011-03-20 kinaba: class ProductAndSum { public: 96fdfab500 2011-03-20 kinaba: int getSum(int p2, int p3, int p5, int p7, int S) 96fdfab500 2011-03-20 kinaba: { 96fdfab500 2011-03-20 kinaba: // Precomputing n!, 1/n!, and 111...111 96fdfab500 2011-03-20 kinaba: vector<mint> FACT(2501), FACT_INV(2501), ONES(2501); 96fdfab500 2011-03-20 kinaba: FACT[0] = FACT_INV[0] = 1; 96fdfab500 2011-03-20 kinaba: ONES[0] = 0; 96fdfab500 2011-03-20 kinaba: for(int n=1; n<FACT.size(); ++n) 96fdfab500 2011-03-20 kinaba: { 96fdfab500 2011-03-20 kinaba: FACT[n] = FACT[n-1] * n; 96fdfab500 2011-03-20 kinaba: FACT_INV[n] = 1 / FACT[n]; 96fdfab500 2011-03-20 kinaba: ONES[n] = ONES[n-1]*10 + 1; 96fdfab500 2011-03-20 kinaba: } 96fdfab500 2011-03-20 kinaba: 96fdfab500 2011-03-20 kinaba: mint answer = 0; 96fdfab500 2011-03-20 kinaba: 96fdfab500 2011-03-20 kinaba: // Exhaustive search over the number of 4,6,8,9s : at most 33*50*50*100 < 8M iterations 96fdfab500 2011-03-20 kinaba: for(int v8=0; v8*3<=p2; ++v8) 96fdfab500 2011-03-20 kinaba: for(int v4=0; v4*2+v8*3<=p2; ++v4) 96fdfab500 2011-03-20 kinaba: for(int v9=0; v9*2<=p3; ++v9) 96fdfab500 2011-03-20 kinaba: for(int v6=0; v6+v4*2+v8*3<=p2 && v6+v9*2<=p3; ++v6) 96fdfab500 2011-03-20 kinaba: { 96fdfab500 2011-03-20 kinaba: // then, the number of 1,2,3s are computable 96fdfab500 2011-03-20 kinaba: int v[] = {-1, -1, p2-v8*3-v4*2-v6, p3-v9*2-v6, v4, p5, v6, p7, v8, v9}; 96fdfab500 2011-03-20 kinaba: { 96fdfab500 2011-03-20 kinaba: int v1 = S; 96fdfab500 2011-03-20 kinaba: for(int i=2; i<=9; ++i) 96fdfab500 2011-03-20 kinaba: v1 -= i * v[i]; 96fdfab500 2011-03-20 kinaba: if( v1 < 0 ) 96fdfab500 2011-03-20 kinaba: continue; 96fdfab500 2011-03-20 kinaba: v[1] = v1; 96fdfab500 2011-03-20 kinaba: } 96fdfab500 2011-03-20 kinaba: int N = accumulate(v+1, v+10, 0); 96fdfab500 2011-03-20 kinaba: 96fdfab500 2011-03-20 kinaba: // Now, let's compute the sum of all integers, who have N digits and #d = v[d], in constant time! 96fdfab500 2011-03-20 kinaba: 96fdfab500 2011-03-20 kinaba: // It can be calculated as follows: 96fdfab500 2011-03-20 kinaba: // Q: how many of the integers have, say "1" in the last digit? 96fdfab500 2011-03-20 kinaba: // A: it is, of course, C(N-1, v[1]-1, v[2], ..., v[9]) 96fdfab500 2011-03-20 kinaba: // where C(k,a,b,..) is the # of ways of spliting k elements into groups of size a, b, ... 96fdfab500 2011-03-20 kinaba: // So, the sum of the least digits of the integers are 96fdfab500 2011-03-20 kinaba: // X = \Sigma_{d=1..9} (d * C(N-1, v[1], v[2], ..., v[d]-1, ..., v[9])) 96fdfab500 2011-03-20 kinaba: // By the same argument, the sum of the second-last digits (10-no-kurai in japanese) is 96fdfab500 2011-03-20 kinaba: // 10 * X 96fdfab500 2011-03-20 kinaba: // For hundreds, the sum is 100*X, and so on. Eventualy, the sum of whole integers is 96fdfab500 2011-03-20 kinaba: // t = (1+10+...+10^N) * X 96fdfab500 2011-03-20 kinaba: // = 111...111 * \Sigma_{d=1..9} (d * C(N-1, v[1], v[2], ..., v[d]-1, ..., v[9])) 96fdfab500 2011-03-20 kinaba: // Let us simplify the formula by using C(k,a,b,...) = k! / a!b!... 96fdfab500 2011-03-20 kinaba: // t = 111...111 * \Sigma_{d=1..9} (d * (N-1)! / v[1]! / ... / v[9]! * v[d]) 96fdfab500 2011-03-20 kinaba: // = 111...111 * (N-1)! / v[1]! / ... / v[9]! * \Sigma_{d=1..9} (d*v[d]) 96fdfab500 2011-03-20 kinaba: // = 111...111 * (N-1)! / v[1]! / ... / v[9]! * S 96fdfab500 2011-03-20 kinaba: // That's it! 96fdfab500 2011-03-20 kinaba: 96fdfab500 2011-03-20 kinaba: mint t = ONES[N] * FACT[N-1] * S; 96fdfab500 2011-03-20 kinaba: for(int i=1; i<=9; ++i) 96fdfab500 2011-03-20 kinaba: t = t * FACT_INV[v[i]]; 96fdfab500 2011-03-20 kinaba: answer = answer + t; 96fdfab500 2011-03-20 kinaba: } 96fdfab500 2011-03-20 kinaba: return answer.val; 96fdfab500 2011-03-20 kinaba: } 96fdfab500 2011-03-20 kinaba: }; 96fdfab500 2011-03-20 kinaba: 96fdfab500 2011-03-20 kinaba: // BEGIN CUT HERE 96fdfab500 2011-03-20 kinaba: #include <ctime> 96fdfab500 2011-03-20 kinaba: double start_time; string timer() 96fdfab500 2011-03-20 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 96fdfab500 2011-03-20 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) 96fdfab500 2011-03-20 kinaba: { os << "{ "; 96fdfab500 2011-03-20 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) 96fdfab500 2011-03-20 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } 96fdfab500 2011-03-20 kinaba: void verify_case(const int& Expected, const int& Received) { 96fdfab500 2011-03-20 kinaba: bool ok = (Expected == Received); 96fdfab500 2011-03-20 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; 96fdfab500 2011-03-20 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } 96fdfab500 2011-03-20 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); 96fdfab500 2011-03-20 kinaba: #define END verify_case(_, ProductAndSum().getSum(p2, p3, p5, p7, S));} 96fdfab500 2011-03-20 kinaba: int main(){ 96fdfab500 2011-03-20 kinaba: 96fdfab500 2011-03-20 kinaba: CASE(0) 96fdfab500 2011-03-20 kinaba: int p2 = 2; 96fdfab500 2011-03-20 kinaba: int p3 = 0; 96fdfab500 2011-03-20 kinaba: int p5 = 0; 96fdfab500 2011-03-20 kinaba: int p7 = 0; 96fdfab500 2011-03-20 kinaba: int S = 4; 96fdfab500 2011-03-20 kinaba: int _ = 26; 96fdfab500 2011-03-20 kinaba: END 96fdfab500 2011-03-20 kinaba: CASE(1) 96fdfab500 2011-03-20 kinaba: int p2 = 0; 96fdfab500 2011-03-20 kinaba: int p3 = 0; 96fdfab500 2011-03-20 kinaba: int p5 = 0; 96fdfab500 2011-03-20 kinaba: int p7 = 0; 96fdfab500 2011-03-20 kinaba: int S = 10; 96fdfab500 2011-03-20 kinaba: int _ = 110109965; 96fdfab500 2011-03-20 kinaba: END 96fdfab500 2011-03-20 kinaba: CASE(2) 96fdfab500 2011-03-20 kinaba: int p2 = 2; 96fdfab500 2011-03-20 kinaba: int p3 = 0; 96fdfab500 2011-03-20 kinaba: int p5 = 0; 96fdfab500 2011-03-20 kinaba: int p7 = 0; 96fdfab500 2011-03-20 kinaba: int S = 5; 96fdfab500 2011-03-20 kinaba: int _ = 610; 96fdfab500 2011-03-20 kinaba: END 96fdfab500 2011-03-20 kinaba: CASE(3) 96fdfab500 2011-03-20 kinaba: int p2 = 1; 96fdfab500 2011-03-20 kinaba: int p3 = 1; 96fdfab500 2011-03-20 kinaba: int p5 = 1; 96fdfab500 2011-03-20 kinaba: int p7 = 1; 96fdfab500 2011-03-20 kinaba: int S = 10; 96fdfab500 2011-03-20 kinaba: int _ = 0; 96fdfab500 2011-03-20 kinaba: END 96fdfab500 2011-03-20 kinaba: CASE(4) 96fdfab500 2011-03-20 kinaba: int p2 = 5; 96fdfab500 2011-03-20 kinaba: int p3 = 5; 96fdfab500 2011-03-20 kinaba: int p5 = 5; 96fdfab500 2011-03-20 kinaba: int p7 = 5; 96fdfab500 2011-03-20 kinaba: int S = 100; 96fdfab500 2011-03-20 kinaba: int _ = 61610122; 96fdfab500 2011-03-20 kinaba: END 96fdfab500 2011-03-20 kinaba: CASE(5) 96fdfab500 2011-03-20 kinaba: int p2 = 100; 96fdfab500 2011-03-20 kinaba: int p3 = 100; 96fdfab500 2011-03-20 kinaba: int p5 = 100; 96fdfab500 2011-03-20 kinaba: int p7 = 100; 96fdfab500 2011-03-20 kinaba: int S = 2500; 96fdfab500 2011-03-20 kinaba: int _ = -1; 96fdfab500 2011-03-20 kinaba: END 96fdfab500 2011-03-20 kinaba: /* 96fdfab500 2011-03-20 kinaba: CASE(6) 96fdfab500 2011-03-20 kinaba: int p2 = ; 96fdfab500 2011-03-20 kinaba: int p3 = ; 96fdfab500 2011-03-20 kinaba: int p5 = ; 96fdfab500 2011-03-20 kinaba: int p7 = ; 96fdfab500 2011-03-20 kinaba: int S = ; 96fdfab500 2011-03-20 kinaba: int _ = ; 96fdfab500 2011-03-20 kinaba: END 96fdfab500 2011-03-20 kinaba: */ 96fdfab500 2011-03-20 kinaba: } 96fdfab500 2011-03-20 kinaba: // END CUT HERE