//#define DEBUG #ifndef DEBUG #define NDEBUG #endif #include <iostream> #include <vector> #include <assert.h> using namespace std; #ifdef DEBUG #define D(...) __VA_ARGS__ #else #define D(...) do {} while(0) #endif struct Range { int c, d; Range(int c, int d) : c(c), d(d) { }; }; vector<Range> students; const int mod = 1000000007; struct TeamSet { int teams; int combinations; // modulo mod TeamSet(int teams = 0, int combinations = 0) : teams(teams), combinations(combinations) {}; }; vector<TeamSet> best_team_sets; int main(int argc, char **argv) { ios_base::sync_with_stdio(false); int n; cin >> n; students.reserve(n); for(int i=0; i<n; i++) { int c, d; cin >> c >> d; assert(1 <= c); assert(c <= d); assert(d <= n); students.emplace_back(c,d); } best_team_sets.resize(n); for(int i=0; i<n; i++) { assert(best_team_sets[i].teams == 0); assert(best_team_sets[i].combinations == 0); } for(int i=0; i<n; i++) { int c = students[i].c; int d = students[i].d; D(cerr << "c: " << c << "; d: " << d << endl); int j; for(j = 1; j <= d && i-j >= -1; j++) { D(cerr << "c: " << c << "; j: " << j << "; d: " << d << endl); auto &s = students[i-j+1]; if(s.c > c) { D(cerr << "c increased from " << c << " to " << s.c << endl); c = s.c; } if(s.d < d) { D(cerr << "d decreased from " << d << " to " << s.d << endl); d = s.d; if(j > d) { break; } } if(j >= c) { TeamSet btsij; if(i-j >= 0) { btsij = best_team_sets[i-j]; if(!btsij.teams) { continue; } btsij.teams++; } else { assert(i-j == -1); btsij.teams = 1; btsij.combinations = 1; } if(btsij.teams > best_team_sets[i].teams) { best_team_sets[i] = btsij; D(cerr << "new combinations count: " << best_team_sets[i].combinations << endl); } else if(btsij.teams == best_team_sets[i].teams) { D(cerr << "increased combinations count from " << best_team_sets[i].combinations); best_team_sets[i].combinations = (best_team_sets[i].combinations + btsij.combinations) % mod; D(cerr << " to " << best_team_sets[i].combinations << endl); } } } D(cerr << "i: " << i << " teams: " << best_team_sets[i].teams << " combinations: " << best_team_sets[i].combinations << endl); } if(best_team_sets[n-1].teams) { cout << best_team_sets[n-1].teams << " " << best_team_sets[n-1].combinations << endl; } else { cout << "NIE" << endl; } return 0; }
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | //#define DEBUG #ifndef DEBUG #define NDEBUG #endif #include <iostream> #include <vector> #include <assert.h> using namespace std; #ifdef DEBUG #define D(...) __VA_ARGS__ #else #define D(...) do {} while(0) #endif struct Range { int c, d; Range(int c, int d) : c(c), d(d) { }; }; vector<Range> students; const int mod = 1000000007; struct TeamSet { int teams; int combinations; // modulo mod TeamSet(int teams = 0, int combinations = 0) : teams(teams), combinations(combinations) {}; }; vector<TeamSet> best_team_sets; int main(int argc, char **argv) { ios_base::sync_with_stdio(false); int n; cin >> n; students.reserve(n); for(int i=0; i<n; i++) { int c, d; cin >> c >> d; assert(1 <= c); assert(c <= d); assert(d <= n); students.emplace_back(c,d); } best_team_sets.resize(n); for(int i=0; i<n; i++) { assert(best_team_sets[i].teams == 0); assert(best_team_sets[i].combinations == 0); } for(int i=0; i<n; i++) { int c = students[i].c; int d = students[i].d; D(cerr << "c: " << c << "; d: " << d << endl); int j; for(j = 1; j <= d && i-j >= -1; j++) { D(cerr << "c: " << c << "; j: " << j << "; d: " << d << endl); auto &s = students[i-j+1]; if(s.c > c) { D(cerr << "c increased from " << c << " to " << s.c << endl); c = s.c; } if(s.d < d) { D(cerr << "d decreased from " << d << " to " << s.d << endl); d = s.d; if(j > d) { break; } } if(j >= c) { TeamSet btsij; if(i-j >= 0) { btsij = best_team_sets[i-j]; if(!btsij.teams) { continue; } btsij.teams++; } else { assert(i-j == -1); btsij.teams = 1; btsij.combinations = 1; } if(btsij.teams > best_team_sets[i].teams) { best_team_sets[i] = btsij; D(cerr << "new combinations count: " << best_team_sets[i].combinations << endl); } else if(btsij.teams == best_team_sets[i].teams) { D(cerr << "increased combinations count from " << best_team_sets[i].combinations); best_team_sets[i].combinations = (best_team_sets[i].combinations + btsij.combinations) % mod; D(cerr << " to " << best_team_sets[i].combinations << endl); } } } D(cerr << "i: " << i << " teams: " << best_team_sets[i].teams << " combinations: " << best_team_sets[i].combinations << endl); } if(best_team_sets[n-1].teams) { cout << best_team_sets[n-1].teams << " " << best_team_sets[n-1].combinations << endl; } else { cout << "NIE" << endl; } return 0; } |