#include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #include <vector> #include <map> #include <set> #include <utility> using namespace std; typedef long long int int64; void dump(int n, int* arr){ for(int lx = 0;lx < n;lx++) printf("%d ", arr[lx]); puts(""); return; } struct minbst{ vector<int> tree; int base; minbst(int n, int* arr){ base = (1<<(int)(ceil(log2(n+3))))-1; tree = vector<int>(base*2+2, 2000000000); for(int lx = 0;lx<n;lx++) tree[lx+base+2] = arr[lx]; for(int lx = base;lx;lx--) tree[lx] = min(tree[lx<<1], tree[(lx<<1)^1]); return; } int query(int a, int b){ int ans = 2000000000; for(a += base+1, b+=base+3; a^b^1;a>>=1, b>>=1){ if(~a&1) ans = min(ans, tree[a^1]); if(b&1) ans = min(ans, tree[b^1]); } return ans; } }; int n; int arr[200000]; int bas[200000] = {0}; int poi[200001] = {0}; int ans[200001]; int main(){ scanf("%d", &n); for(int lx = 0;lx < n;lx++) scanf("%d", arr+lx); //dump(n, arr); for(int _ = 0; _ < 2;_++){ minbst bst(n, arr); for(int lx = 0;lx < n;lx++){ int ll = 0, rr = n-lx; while(ll < rr-1){ int test = (ll+rr)>>1; if(bst.query(lx, lx+test) >= arr[lx]) ll = test; else rr = test; } bas[lx] += ll; } //dump(n, bas); reverse(arr, arr+n); reverse(bas, bas+n); } for(int lx = 0;lx < n;lx++) poi[bas[lx]+1] = max(arr[lx], poi[bas[lx]+1]); //dump(n, poi); int mm = 0; for(int lx = n;lx;lx--){ mm = max(mm, poi[lx]); ans[lx-1] = mm; } dump(n, ans); return 0; }
2015年5月27日 星期三
Codeforces Round #305 (Div. 1), problem: (B) Mike and Feet
用線段樹加減暴力尻過
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言