hdu 6070(二分 线段树区间维护)
二分mid
size(l, r) / (r - l + 1) <= mid -> size(l, r) <= mid * (r - l + 1) -> size(l, r) + mid * l <= mid * (r + 1)
暴力枚举r线段树维护左边的式子
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <string> #include <cmath> using namespace std; const int maxn = 60005; const double EPS = 1e-7; double tree[maxn * 4]; int lazy[maxn * 4], a[maxn], vis[maxn], pre[maxn]; void build(int l, int r, int o, double t) { if(l == r) { tree[o] = t * l; lazy[o] = 0; } else { int mid = (l + r) >> 1; build(l, mid, o * 2, t); build(mid + 1, r, o * 2 + 1, t); lazy[o] = 0; tree[o] = min(tree[o * 2], tree[o * 2 + 1]); } } int x1, x2; void pushdown(int o) { tree[o * 2] += lazy[o]; lazy[o * 2] += lazy[o]; tree[o * 2 + 1] += lazy[o]; lazy[o * 2 + 1] += lazy[o]; lazy[o] = 0; } void update(int l, int r, int o) { if(x1 <= l && r <= x2) { ++lazy[o]; tree[o] += 1; } else { pushdown(o); int mid = (l + r) >> 1; if(x1 <= mid) update(l, mid, o * 2); if(x2 > mid) update(mid + 1, r, o * 2 + 1); tree[o] = min(tree[o * 2], tree[o * 2 + 1]); } } double query(int l, int r, int o) { if(x1 <= l && r <= x2) { return tree[o]; } else { pushdown(o); int mid = (l + r) >> 1; double ret; if(x2 <= mid) ret = query(l, mid, o * 2); else if(x1 > mid) ret = query(mid + 1, r, o * 2 + 1); else ret = min(query(l, mid, o * 2), query(mid + 1, r, o * 2 + 1)); tree[o] = min(tree[o * 2], tree[o * 2 + 1]); return ret; } } void print(int l, int r, int o) { if(l == r) { cout << "l == " << l << " r == " << r << " o == " << o << endl; cout << "tree == " << tree[o] << " lazy == " << lazy[o] << endl; return ; } else { int mid = (l + r) >> 1; print(l, mid, o * 2); print(mid + 1, r, o * 2 + 1); cout << "l == " << l << " r == " << r << " o == " << o << endl; cout << "tree == " << tree[o] << " lazy == " << lazy[o] << endl; } } int main() { int T; scanf("%d", &T); while(T--) { memset(vis, 0, sizeof(vis)); int n; scanf("%d", &n); for(int i = 1; i <= n; ++i) { scanf("%d", &a[i]); } for(int i = 1; i <= n; ++i) { pre[i] = vis[a[i]]; vis[a[i]] = i; } double l = 0, r = 1; while(fabs(r - l) > EPS) { double mid = (l + r) / 2; int flag = 0; build(1, n, 1, mid); for(int i = 1; i <= n; ++i) { x1 = pre[i] + 1, x2 = i; update(1, n, 1); x1 = 1, x2 = i; double tmp = query(1, n, 1); // for(int j = 1; j <= n; ++j) // { // x1 = x2 = j; // cout << query(1, n, 1) << " "; // } // cout << endl; // cout << "i == " << i << endl; // print(1, n, 1); // if(mid == 0.25) // { // cout << "tmp == " << tmp << endl; // } if(tmp < mid * (i + 1)) { // cout << "tmp == " << tmp << endl; // cout << "****" << endl; // cout << "i == " << i << " tmp == " << tmp << " mid == " << mid << endl; flag = 1; break; } } if(flag) { r = mid; } else { l = mid; } } printf("%.6f\n", l); } }

浙公网安备 33010602011771号