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 <cstdio> #include <algorithm> #include <cstring>
inline int max(const int x, const int y) {return x > y ? x : y;} inline int min(const int x, const int y) {return x < y ? x : y;} int f1[50005], f2[50005], h[50005], v[50005], n; double g1[50005], g2[50005]; struct Node { int x, y, z; inline bool operator < (const Node a) const {return x < a.x;} } a[50005]; struct Initer { int v, id; inline bool operator < (const Initer a) {return v < a.v;} } b[50005]; struct cmp { inline bool operator () (const Node a, const Node b) const {return a.y < b.y;} }; struct cmp2 { inline bool operator() (const Node a, const Node b) {return a.x > b.x;} }; struct BIT { int nowtime, c[50005], t[50005]; double cnt[50005]; void update(int x, int d, double d2) { for (int i = x; i <= n; i += (i & ~i + 1)) if (nowtime ^ t[i]) t[i] = nowtime, c[i] = d, cnt[i] = d2; else { if (c[i] < d) c[i] = d, cnt[i] = d2; else if (c[i] == d) cnt[i] += d2; } } inline std::pair<int, double> query(int x) { int sum = 0; double sum2 = 0; for (int i = x; i; i -= (i & ~i + 1)) if (nowtime == t[i]) { if (sum < c[i]) sum = c[i], sum2 = cnt[i]; else if (sum == c[i]) sum2 += cnt[i]; } return std::make_pair(sum, sum2); } inline void clear() {++ nowtime;} } bitf;
void CDQ1(int l, int r) { if (l == r) return; int mid = l + r >> 1, i = l, j = mid + 1; CDQ1(l, mid); std::sort(a + l, a + mid + 1, cmp()), std::sort(a + mid + 1, a + r + 1, cmp()); while (i <= mid && j <= r) { if (a[i].y <= a[j].y) bitf.update(a[i].z, f1[a[i].x], g1[a[i].x]), ++ i; else { std::pair<int, double> ans = bitf.query(a[j].z); if (ans.first + 1 > f1[a[j].x]) f1[a[j].x] = ans.first + 1, g1[a[j].x] = ans.second; else if (ans.first + 1 == f1[a[j].x]) g1[a[j].x] += ans.second; ++ j; } } while (j <= r) { std::pair<int, double> ans = bitf.query(a[j].z); if (ans.first + 1 > f1[a[j].x]) f1[a[j].x] = ans.first + 1, g1[a[j].x] = ans.second; else if (ans.first + 1 == f1[a[j].x]) g1[a[j].x] += ans.second; ++ j; } std::sort(a + mid + 1, a + r + 1); bitf.clear(), CDQ1(mid + 1, r); } void CDQ2(int l, int r) { if (l == r) return; int mid = l + r >> 1, i = l, j = mid + 1; CDQ2(l, mid); std::sort(a + l, a + mid + 1, cmp()), std::sort(a + mid + 1, a + r + 1, cmp()); while (i <= mid && j <= r) { if (a[i].y <= a[j].y) bitf.update(a[i].z, f2[a[i].x], g2[a[i].x]), ++ i; else { std::pair<int, double> ans = bitf.query(a[j].z); if (ans.first + 1 > f2[a[j].x]) f2[a[j].x] = ans.first + 1, g2[a[j].x] = ans.second; else if (ans.first + 1 == f2[a[j].x]) g2[a[j].x] += ans.second; ++ j; } } while (j <= r) { std::pair<int, double> ans = bitf.query(a[j].z); if (ans.first + 1 > f2[a[j].x]) f2[a[j].x] = ans.first + 1, g2[a[j].x] = ans.second; else if (ans.first + 1 == f2[a[j].x]) g2[a[j].x] += ans.second; ++ j; } std::sort(a + mid + 1, a + r + 1, cmp2()); bitf.clear(), CDQ2(mid + 1, r); }
void init(int *a, int &mx) { for (int i = 1; i <= n; ++ i) b[i].id = i, b[i].v = a[i]; std::sort(b + 1, b + n + 1); for (int i = 1; i <= n; ++ i) a[b[i].id] = a[b[i - 1].id] + 1 - (b[i].v == b[i - 1].v); mx = a[b[n].id] + 1; for (int i = 1; i <= n; ++ i) a[i] = mx - a[i]; }
int main() { int mxh, mxv; scanf("%d", &n); for (int i = 1; i <= n; ++ i) scanf("%d%d", h + i, v + i), f1[i] = g1[i] = f2[i] = g2[i] = 1; init(h, mxh), init(v, mxv); for (int i = 1; i <= n; ++ i) a[i].x = i, a[i].y = h[i], a[i].z = v[i]; CDQ1(1, n); int ans = 0; double sum = 0; for (int i = 1; i <= n; ++ i) ans = max(ans, f1[i]); for (int i = 1; i <= n; ++ i) if (f1[i] == ans) sum += g1[i]; printf("%d\n", ans); std::sort(a + 1, a + n + 1); std::reverse(a + 1, a + n + 1); for (int i = 1; i <= n; ++ i) a[i].y = mxh - a[i].y, a[i].z = mxv - a[i].z; CDQ2(1, n); for (int i = 1; i <= n; ++ i) if (f1[i] + f2[i] - 1 == ans) printf("%.5lf ", g1[i] * g2[i] / sum); else printf("0.00000 "); return 0; }
|