#include <stdlib.h> //---===--- #include <stdio.h> #include <unistd.h> typedef unsigned int uint; char buf_in[4096000]; int buf_in_head = 0; int buf_in_tail = 0; static int getChar(void) { while (buf_in_head == buf_in_tail) { int rv = read(0, buf_in, sizeof(buf_in)); if (rv > 0) { buf_in_head = 0; buf_in_tail = rv; break; }; if (rv == 0) return EOF; } return buf_in[buf_in_head++]; } // only 1 call is safe, and only if previously getChar() had been called. static void ungetChar(void) { --buf_in_head; } static uint getUInt() { uint v; int c; for (;;) { c = getChar(); if (c < '0') continue; if (c > '9') continue; v = c - '0'; break; }; for (;;) { c = getChar(); if (c < '0') break; if (c > '9') break; v *= 10; v += c - '0'; }; ungetChar(); return v; } //---===--- #define MOD (1000000000 + 7) int n; #define H1 typedef struct { uint c, d, ways, splits; #ifdef H1 uint max_splits; #endif /* H1 */ } tt; tt T[1000000+1]; #define POSSIBLE(_i_) (T[_i_].ways | T[_i_].splits) int main (void) { int i, j; // 1 <= n <= 1,000,000 n = getUInt(); for (i = 1; i <= n; ++i) { // 1 <= c[i] <= d[i] <= n T[i].c = getUInt(); T[i].d = getUInt(); }; T[0].ways = 1; T[0].splits = 0; #ifdef H1 T[0].max_splits = 0; #endif /* H1 */ //printf("*** 0: ways:1 splits:0 max_splits:0\n"); for (i = 1; i <= n; ++i) { uint cnt = 0, min = 0, max = i, w = 0, s = 0; for (j = 0; j < i; ++j) { uint k = i - j; // i > j, hence k >= 1 ++cnt; if (T[k].c > min) min = T[k].c; if (T[k].d < max) max = T[k].d; --k; // k >= 0; #ifdef H1 if (T[k].max_splits + 1 < s) break; // won't see anything useful #endif /* H1 */ if (cnt > max) break; // too much if (cnt < min) continue; // not enough // valid //printf("%d: %d --> %d\n", i, j, k); if (!POSSIBLE(k)) continue; if (T[k].splits + 1 > s) { s = T[k].splits + 1; w = T[k].ways; } else if (T[k].splits + 1 == s) { w += T[k].ways; if (w > MOD) w -= MOD; }; }; T[i].ways = w; T[i].splits = s; #ifdef H1 T[i].max_splits = T[i - 1].max_splits; if (s > T[i].max_splits) T[i].max_splits = s; #endif /* H1 */ //printf("*** %d: ways:%u splits:%u max_splits:%u\n", i, w, s, T[i].max_splits); }; if (POSSIBLE(n)) { printf("%d %d\n", T[n].splits, T[n].ways); } else { printf("NIE\n"); }; 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 126 127 128 129 | #include <stdlib.h> //---===--- #include <stdio.h> #include <unistd.h> typedef unsigned int uint; char buf_in[4096000]; int buf_in_head = 0; int buf_in_tail = 0; static int getChar(void) { while (buf_in_head == buf_in_tail) { int rv = read(0, buf_in, sizeof(buf_in)); if (rv > 0) { buf_in_head = 0; buf_in_tail = rv; break; }; if (rv == 0) return EOF; } return buf_in[buf_in_head++]; } // only 1 call is safe, and only if previously getChar() had been called. static void ungetChar(void) { --buf_in_head; } static uint getUInt() { uint v; int c; for (;;) { c = getChar(); if (c < '0') continue; if (c > '9') continue; v = c - '0'; break; }; for (;;) { c = getChar(); if (c < '0') break; if (c > '9') break; v *= 10; v += c - '0'; }; ungetChar(); return v; } //---===--- #define MOD (1000000000 + 7) int n; #define H1 typedef struct { uint c, d, ways, splits; #ifdef H1 uint max_splits; #endif /* H1 */ } tt; tt T[1000000+1]; #define POSSIBLE(_i_) (T[_i_].ways | T[_i_].splits) int main (void) { int i, j; // 1 <= n <= 1,000,000 n = getUInt(); for (i = 1; i <= n; ++i) { // 1 <= c[i] <= d[i] <= n T[i].c = getUInt(); T[i].d = getUInt(); }; T[0].ways = 1; T[0].splits = 0; #ifdef H1 T[0].max_splits = 0; #endif /* H1 */ //printf("*** 0: ways:1 splits:0 max_splits:0\n"); for (i = 1; i <= n; ++i) { uint cnt = 0, min = 0, max = i, w = 0, s = 0; for (j = 0; j < i; ++j) { uint k = i - j; // i > j, hence k >= 1 ++cnt; if (T[k].c > min) min = T[k].c; if (T[k].d < max) max = T[k].d; --k; // k >= 0; #ifdef H1 if (T[k].max_splits + 1 < s) break; // won't see anything useful #endif /* H1 */ if (cnt > max) break; // too much if (cnt < min) continue; // not enough // valid //printf("%d: %d --> %d\n", i, j, k); if (!POSSIBLE(k)) continue; if (T[k].splits + 1 > s) { s = T[k].splits + 1; w = T[k].ways; } else if (T[k].splits + 1 == s) { w += T[k].ways; if (w > MOD) w -= MOD; }; }; T[i].ways = w; T[i].splits = s; #ifdef H1 T[i].max_splits = T[i - 1].max_splits; if (s > T[i].max_splits) T[i].max_splits = s; #endif /* H1 */ //printf("*** %d: ways:%u splits:%u max_splits:%u\n", i, w, s, T[i].max_splits); }; if (POSSIBLE(n)) { printf("%d %d\n", T[n].splits, T[n].ways); } else { printf("NIE\n"); }; return 0; } |