ADDED SRM/673-U/1A.cpp Index: SRM/673-U/1A.cpp ================================================================== --- SRM/673-U/1A.cpp +++ SRM/673-U/1A.cpp @@ -0,0 +1,153 @@ +#include <iostream> +#include <sstream> +#include <iomanip> +#include <vector> +#include <string> +#include <map> +#include <set> +#include <algorithm> +#include <numeric> +#include <iterator> +#include <functional> +#include <complex> +#include <queue> +#include <stack> +#include <cmath> +#include <cassert> +#include <tuple> +using namespace std; +typedef long long LL; +typedef complex<double> CMP; + +static const unsigned MODVAL = 1000000007; +struct mint +{ + unsigned val; + mint():val(0){} + mint(int x):val(x%MODVAL) {} + mint(unsigned 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; } + +class BearCavalry { public: + int countAssignments(vector <int> warriors, vector <int> horses) + { + mint total = 0; + + const int W = warriors[0]; + warriors.erase(warriors.begin()); + sort(warriors.begin(), warriors.end()); + sort(horses.begin(), horses.end()); + + for(int x=0; x<horses.size(); ++x) { + const int H = horses[x]; + vector<int> hs(horses.begin(), horses.begin()+x); + hs.insert(hs.end(), horses.begin()+x+1, horses.end()); + total += cnt(W*H, warriors, hs); + } + return total.val; + } + + mint cnt(int TOP, vector<int> w, vector<int> h) + { + mint total = 1; + for(int i=0; i<w.size(); ++i) { + int W = w[w.size()-1-i]; + + int c=0; + for(int hk: h) + c += (hk*W < TOP); + c -= i; + if(c <= 0) + return 0; + total *= c; + } + return total; + } +}; + +// BEGIN CUT HERE +#include <ctime> +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) + { os << "{ "; + for(typename vector<T>::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(_, BearCavalry().countAssignments(warriors, horses));} +int main(){ + +CASE(0) + int warriors_[] = {5,8,4,8}; + vector <int> warriors(warriors_, warriors_+sizeof(warriors_)/sizeof(*warriors_)); + int horses_[] = {19,40,25,20}; + vector <int> horses(horses_, horses_+sizeof(horses_)/sizeof(*horses_)); + int _ = 2; +END +CASE(1) + int warriors_[] = {1,1}; + vector <int> warriors(warriors_, warriors_+sizeof(warriors_)/sizeof(*warriors_)); + int horses_[] = {1,1}; + vector <int> horses(horses_, horses_+sizeof(horses_)/sizeof(*horses_)); + int _ = 0; +END +CASE(2) + int warriors_[] = {10,2,10}; + vector <int> warriors(warriors_, warriors_+sizeof(warriors_)/sizeof(*warriors_)); + int horses_[] = {100,150,200}; + vector <int> horses(horses_, horses_+sizeof(horses_)/sizeof(*horses_)); + int _ = 3; +END +CASE(3) + int warriors_[] = {10,20}; + vector <int> warriors(warriors_, warriors_+sizeof(warriors_)/sizeof(*warriors_)); + int horses_[] = {1,3}; + vector <int> horses(horses_, horses_+sizeof(horses_)/sizeof(*horses_)); + int _ = 1; +END +CASE(4) + int warriors_[] = {20,20,25,23,24,24,21}; + vector <int> warriors(warriors_, warriors_+sizeof(warriors_)/sizeof(*warriors_)); + int horses_[] = {20,25,25,20,25,23,20}; + vector <int> horses(horses_, horses_+sizeof(horses_)/sizeof(*horses_)); + int _ = 0; +END +CASE(5) + int warriors_[] = {970,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800, +800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800}; + vector <int> warriors(warriors_, warriors_+sizeof(warriors_)/sizeof(*warriors_)); + int horses_[] = {1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000, +1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000, +1000,1000,1000,1000,1000,1000,1000,1000,1000,1000}; + vector <int> horses(horses_, horses_+sizeof(horses_)/sizeof(*horses_)); + int _ = 318608048; +END +/* +CASE(6) + int warriors_[] = ; + vector <int> warriors(warriors_, warriors_+sizeof(warriors_)/sizeof(*warriors_)); + int horses_[] = ; + vector <int> horses(horses_, horses_+sizeof(horses_)/sizeof(*horses_)); + int _ = ; +END +CASE(7) + int warriors_[] = ; + vector <int> warriors(warriors_, warriors_+sizeof(warriors_)/sizeof(*warriors_)); + int horses_[] = ; + vector <int> horses(horses_, horses_+sizeof(horses_)/sizeof(*horses_)); + int _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/673-U/1B-U.cpp Index: SRM/673-U/1B-U.cpp ================================================================== --- SRM/673-U/1B-U.cpp +++ SRM/673-U/1B-U.cpp @@ -0,0 +1,180 @@ +#include <iostream> +#include <sstream> +#include <iomanip> +#include <vector> +#include <string> +#include <map> +#include <set> +#include <algorithm> +#include <numeric> +#include <iterator> +#include <functional> +#include <complex> +#include <queue> +#include <stack> +#include <cmath> +#include <cassert> +#include <tuple> +using namespace std; +typedef long long LL; +typedef complex<double> CMP; + +static unsigned MODVAL = 1000000007; +struct mint +{ + unsigned val; + mint():val(0){} + mint(int x):val(x%MODVAL) {} + mint(unsigned 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<mint> > CP_; +mint C(int n, int k) { + while( CP_.size() <= n ) { + int nn = CP_.size(); + CP_.push_back(vector<mint>(nn+1,1)); + for(int kk=1; kk<nn; ++kk) + CP_[nn][kk] = CP_[nn-1][kk-1] + CP_[nn-1][kk]; + } + return k<0 || n<k ? 0 : CP_[n][k]; +} + +class BearPermutations { public: + int countPermutations(int N, int S, int MOD) + { + MODVAL = MOD; + return pat_below(N, S).val; + } + + mint pat_below(int N, int S) { + mint total = 0; + for(int s=0; s<=S; ++s) + total += pat_exact(N, s); + return total; + } + + vector<int> memo3; + int pat_exact(int N, int S) { + memo3.resize(101*101, -1); + auto key = N*101+S; + if(memo3[key]!=-1) + return memo3[key]; + + mint total = 0; + for(int c=0; c<N; ++c) + total += pat_center_exact(N, c, S); + return memo3[key] = total.val; + } + + vector<int> memo2; + int pat_exact_shifted(int N, int S, int score_offset) { + memo2.resize(101*101*101, -1); + auto key = (N*101+score_offset)*101+S; + if(memo2[key]!=-1) + return memo2[key]; + + mint total = 0; + for(int c=0; c<N; ++c) + if(score_offset+c <= S) + total += pat_center_exact(N, c, S-(score_offset+c)); + return memo2[key]=total.val; + } + + vector<int> memo; + int pat_center_exact(int N, int c, int S) + { + c = min(c, N-1-c); + + if(N==1) + return (S==0 ? 1 : 0); + if(c==0 || c==N-1) + return pat_exact(N-1, S); + + memo.resize(101*101*101, -1); + auto key = (N*101+c)*101+S; + if(memo[key]!=-1) + return memo[key]; + + LL total = 0; + for(int cl=0; cl<c; ++cl) + for(int SS=0; SS<=S; ++SS) + total += ((LL)pat_center_exact(c, cl, SS) * pat_exact_shifted(N-c-1, S-SS, (c-cl)+1)) % MODVAL; + return memo[key] = (total * C(N-1, c)).val; + } +}; + +// BEGIN CUT HERE +#include <ctime> +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) + { os << "{ "; + for(typename vector<T>::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(_, BearPermutations().countPermutations(N, S, MOD));} +int main(){ + +CASE(0) + int N = 3; + int S = 1; + int MOD = 71876209; + int _ = 4; +END +CASE(1) + int N = 4; + int S = 0; + int MOD = 1000003; + int _ = 8; +END +CASE(2) + int N = 4; + int S = 1; + int MOD = 483128897; + int _ = 8; +END +CASE(3) + int N = 5; + int S = 3; + int MOD = 907283243; + int _ = 82; +END +CASE(4) + int N = 5; + int S = 100; + int MOD = 101; + int _ = 19; +END +CASE(5) + int N = 20; + int S = 30; + int MOD = 3; + int _ = 2; +END +CASE(6) + int N = 100; + int S = 100; + int MOD = 1000000007; + int _ = -1; +END +/* +CASE(7) + int N = ; + int S = ; + int MOD = ; + int _ = ; +END +*/ +} +// END CUT HERE