BZOJ1113 [Poi2008]海报PLA 【分治 + 线段树】
2018-06-28 10:30
239 查看
题目链接
题解
显然只与高有关,每次选择所有海报中最低的覆盖所有海报,然后分治两边
每个位置会被调用一次,复杂度\(O(nlogn)\)
\(upd:\)智障了,,是一道\(O(n)\)普及-贪心模拟题QAQ
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<map> #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt) #define REP(i,n) for (int i = 1; i <= (n); i++) #define mp(a,b) make_pair<int,int>(a,b) #define cls(s) memset(s,0,sizeof(s)) #define cp pair<int,int> #define LL long long int #define ls (u << 1) #define rs (u << 1 | 1) using namespace std; const int maxn = 250005,maxm = 100005,INF = 1000000000; inline int read(){ int out = 0,flag = 1; char c = getchar(); while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();} while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();} return out * flag; } int h[maxn],n,ans; int pos[maxn << 2],mn[maxn << 2],tag[maxn << 2]; inline void upd(int u){ if (mn[ls] <= mn[rs]) pos[u] = pos[ls]; else pos[u] = pos[rs]; mn[u] = min(mn[ls],mn[rs]); } inline void pd(int u){ if (tag[u]){ mn[ls] += tag[u]; mn[rs] += tag[u]; tag[ls] += tag[u]; tag[rs] += tag[u]; tag[u] = 0; } } void add(int u,int l,int r,int L,int R,int v){ if (l >= L && r <= R){mn[u] += v; tag[u] += v; return;} pd(u); int mid = l + r >> 1; if (mid >= L) add(ls,l,mid,L,R,v); if (mid < R) add(rs,mid + 1,r,L,R,v); upd(u); } cp query(int u,int l,int r,int L,int R){ if (l >= L && r <= R) return mp(mn[u],pos[u]); pd(u); int mid = l + r >> 1; if (mid >= R) return query(ls,l,mid,L,R); if (mid < L) return query(rs,mid + 1,r,L,R); cp t1 = query(ls,l,mid,L,R),t2 = query(rs,mid + 1,r,L,R); return mp(min(t1.first,t2.first),t1.first <= t2.first ? t1.second : t2.second); } void build(int u,int l,int r){ if (l == r){mn[u] = h[l]; pos[u] = l; return;} int mid = l + r >> 1; build(ls,l,mid); build(rs,mid + 1,r); upd(u); } void solve(int l,int r){ if (l > r) return; cp t = query(1,1,n,l,r); if (t.first){ if (t.second > l) add(1,1,n,l,t.second - 1,-t.first); if (t.second < r) add(1,1,n,t.second + 1,r,-t.first); ans++; } solve(l,t.second - 1); solve(t.second + 1,r); } int main(){ n = read(); REP(i,n) read(),h[i] = read(); build(1,1,n); solve(1,n); printf("%d\n",ans); return 0; }
相关文章推荐
- bzoj 1113: [Poi2008]海报PLA 分治
- 【bzoj1113】[Poi2008]海报PLA
- BZOJ 1113: [Poi2008]海报PLA 裸单调栈
- 【BZOJ 1113】 [Poi2008]海报PLA
- [单调栈] BZOJ 1113 [Poi2008]海报PLA & BZOJ 1628 [Usaco2007 Demo]City skyline
- 【bzoj1113】 [Poi2008]海报PLA
- bzoj1113【poi2008】海报PLA
- [BZOJ 1113][Poi2008]海报PLA:单调栈
- BZOJ 1113: [Poi2008]海报PLA
- bzoj 1113: [Poi2008]海报PLA
- BZOJ——T 1113: [Poi2008]海报PLA
- BZOJ 1113 [Poi2008]海报PLA 单调栈
- 【Poi2008】【BZOJ1113】海报PLA
- [bzoj1113][POI2008]海报PLA(单调栈)
- BZOJ 1113 [Poi2008]海报PLA 单调栈
- bzoj1113: [Poi2008]海报PLA
- bzoj1113 [Poi2008]海报PLA(单调栈)
- Bzoj1113:[Poi2008]海报PLA:贪心+单调栈
- bzoj 1113: [Poi2008]海报PLA(栈)
- bzoj1113[Poi2008]海报PLA 单调栈