BZOJ2216【決策單調性】
阿新 • • 發佈:2019-02-01
通過這題學習了決策單調性.順便學習了wmg_1001【科學】的程式碼風格.
/* I will wait for you */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <algorithm> #include <iostream> #include <fstream> #include <vector> #include <queue> #include <deque> #include <set> #include <map> #include <string> #define make make_pair #define fi first #define se second using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> PII; const int maxn = 500010; const int maxm = 1000; const int maxs = 100; const int INF = 1 << 29; const int P = 1000000007; const double error = 1e-9; inline int read() { int x = 0,f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { f = (ch == '-' ? -1 : 1); ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } struct policy { int pos, l, r; } q[maxn]; int n, a[maxn]; double f[maxn], g[maxn]; double cal(int x, int y) { return a[x] + sqrt(abs(x - y)) - a[y]; } double fac(int x, int y, int z) { return cal(x, z) > cal(y, z); } int binary(int x, policy a) { int y = a.pos; int l = a.l, r = a.r; while (l <= r) { int mid = (l + r) / 2; if (fac(x, y ,mid)) r = mid - 1; else l = mid + 1; } return l; } void dp(double *ans) { int head = 1, tail = 0; for (int i = 0; i < n; i++) { q[head].l++; if (head <= tail && q[head].l > q[head].r) head++; if (head > tail || fac(i, q[head].pos, n - 1)) { while (head <= tail && fac(i, q[tail].pos, q[tail].l)) tail--; if (head > tail) q[++tail] = (policy) {i, i, n}; else { int mid = binary(i, q[tail]); q[tail].r = mid - 1; q[++tail] = (policy) {i, mid, n}; } } ans[i] = max(ans[i], cal(q[head].pos, i)); } } int main() { n = read(); for (int i = 0; i < n; i++) a[i] = read(); dp(f); for (int i = 0; i < n / 2; i++) swap(a[i], a[n - i - 1]); dp(g); for (int i = 0; i < n; i++) { double ans = max(f[i], g[n - i - 1]); ans = max(ans, 0.0); printf("%d\n", (int) ceil(ans)); } return 0; }