这道题问的就是有N朵花,可以浇水M天,每天可以浇连续区间长度为W的水,问花的最小值的最大情况是多少?
不妨去二分答案这样的最小值,然后为了节约时间,可以利用线段树来更新,时间复杂度就下降到了O(N * log(INT_MAX)*logN)可以行。
具体代码是这样的:
#include #include #include #include #include #include #include #include #include #include #include #include #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 #define INF 0x3f3f3f3f #define HalF (l + r)>>1 #define lsn rt<<1 #define rsn rt<<1|1 #define Lson lsn, l, mid #define Rson rsn, mid+1, r #define QL Lson, ql, qr #define QR Rson, ql, qr #define myself rt, l, r using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 1e5 + 7; int N, M, W; int a[maxN], minn; int tree[maxN<<2], lazy[maxN<<2]; inline void pushup(int rt) { tree[rt] = min(tree[lsn], tree[rsn]); } void buildTree(int rt, int l, int r) { lazy[rt] = 0; if(l == r) { tree[rt] = a[l]; return; } int mid = HalF; buildTree(Lson); buildTree(Rson); pushup(rt); } inline void pushdown(int rt) { if(lazy[rt]) { tree[lsn] += lazy[rt]; tree[rsn] += lazy[rt]; lazy[lsn] += lazy[rt]; lazy[rsn] += lazy[rt]; lazy[rt] = 0; } } void update(int rt, int l, int r, int ql, int qr, int val) { if(ql <= l && qr >= r) { tree[rt] += val; lazy[rt] += val; return; } pushdown(rt); int mid = HalF; if(qr <= mid) update(QL, val); else if(ql > mid) update(QR, val); else { update(QL, val); update(QR, val); } pushup(rt); } int query(int rt, int l, int r, int pos) { if(l == r) return tree[rt]; pushdown(rt); int mid = HalF; if(pos <= mid) return query(Lson, pos); else return query(Rson, pos); } bool check(int limit) { int needs = 0; buildTree(1, 1, N); for(int i=1; i<=N; i++) { int tmp = query(1, 1, N, i); if(tmp >= limit) continue; int det = limit - tmp; needs += det; if(needs > M) return false; if(W > 1) update(1, 1, N, i + 1, i + W - 1, det); } return true; } int main() { scanf("%d%d%d", &N, &M, &W); minn = INF; for(int i=1; i<=N; i++) { scanf("%d", &a[i]); minn = min(minn, a[i]); } int L = minn, R = INF, mid = 0, ans = minn; while(L <= R) { mid = (L + R)/2; if(check(mid)) { L = mid + 1; ans = mid; } else R = mid - 1; } printf("%d\n", ans); return 0; }