您的位置:首页 > 其它

2016"百度之星“-初赛(Astar Round2B)-A.区间的价值

2016-05-25 12:52 465 查看
每次取出集合中最大的数,放到它对应的位置,如1,6,2,4,4,取出6,放到1位置(从0开始)。
当你取出一个数a时,两边会有一些之前放的数,

,其中a是最小的,假设在



最大,



最大。
那么这一段连续的数可以更新长度为]

的答案,而且是要包含a的一段。一段区间的有效部分是最小值到最大值的一段,我们可以先考虑有效部分,然后用它向上更新。因为a是最小值,最大值要么在b,要么在c,有效区间不会横跨b,c。并且对



的答案要大于

,所以对于b,只需更新

,那么其实可以用

去更新

。同理,对c,只需用

去更新


#include
#include
#include
#include
#include
#include

typedef long long ll;
#define mst(a,k) memset(a, k, sizeof(a))
#define rep(i,s,t) for(int i = s; i < t; i++)
#define lo (o << 1)
#define ro (lo | 1)

using namespace std;

typedef pair pii;

ll Max[400005];

int n;
int a[100005];
ll ans[100005];
pii b[100005];
int have[100005], head[100005], tail[100005], mx[100005];

void build(int l, int r, int o) {
Max[o] = 0;
if(l == r) return;
int mid = l + r >> 1;
build(l, mid, lo);
build(mid + 1, r, ro);
}
void update(int l, int r, int o, int L, int R, ll v) {
if(L <= l && r <= R) {
Max[o] = max(Max[o], v);
return;
}
int mid = l + r >> 1;
if(L <= mid) update(l, mid, lo, L, R, v);
if(mid < R) update(mid + 1, r, ro, L, R, v);
}
void pushdown(int l, int r, int o) {
if(l == r) {
ans[l] = Max[o];
return;
}
int mid = l + r >> 1;
Max[lo] = max(Max[lo], Max[o]);
Max[ro] = max(Max[ro], Max[o]);
pushdown(l, mid, lo);
pushdown(mid + 1, r, ro);
}
int main() {

while(~scanf("%d", &n)) {
rep(i, 1, n + 1) scanf("%d", a + i);
rep(i, 1, n + 1) {
b[i].first = a[i];
b[i].second = i;
}
sort(b + 1, b + n + 1);
mst(have, 0);
build(1, n, 1);
for(int i = n; i >= 1; i--) {
ll v = b[i].first;
int p = b[i].second;
update(1, n, 1, 1, 1, v * v);
head[p] = tail[p] = p;
have[p] = 1;
mx[p] = p;
if(have[p - 1]) {
head[p] = head[p - 1];
tail[head[p]] = p;
int L = p + 1 - mx[head[p]];
int R = p + 1 - head[p];
if(have[p + 1]) R += tail[p + 1]  - p;
update(1, n, 1, L, R, v * a[mx[head[p]]]);
}
if(have[p + 1]) {
int L = mx[p + 1] - p + 1;
int R = tail[p + 1] - p + 1;
if(have[p - 1]) R += p - head[p];
update(1, n, 1, L, R, v * a[mx[p + 1]]);
tail[head[p]] = tail[p + 1];
head[tail[head[p]]] = head[p];
if(a[mx[p + 1]] > a[mx[head[p]]]) {
mx[head[p]] = mx[p + 1];
}
}
}
pushdown(1, n, 1);
for(int i = 1; i <= n; i++) printf("%I64d\n", ans[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息