題目傳送門
題解
分析
分類討論。
記第 i i i 個答案為 a n s i + 1 ans_i+1 ansi?+1。
- 第 i i i 個數就是目前的最大值。
顯然, a n s i = h i × i ans_i=h_i \times i ansi?=hi?×i。 - 第 i i i 個數就是目前的最大值。
記 l a s t i last_i lasti? 為 i i i 前面,從后往前數第一個比 h i h_i hi? 大的 j j j。
所以,填滿第 l a s t i last_i lasti? 個前面的答案為 a n s j ans_j ansj?。
而第 l a s t i + 1 last_i+1 lasti?+1 至 i ? 1 i-1 i?1,顯然要用 [ ( i ? 1 ) ? ( l a s t i + 1 ) + 1 ] × h i = ( i ? l a s t i ? 1 ) × h i [(i - 1) - (last_i + 1) + 1] \times h_i=(i-last_i-1) \times h_i [(i?1)?(lasti?+1)+1]×hi?=(i?lasti??1)×hi? 個格子才能填滿。
所以,這時的 a n s i = ( i ? l a s t i ? 1 ) × h i ans_i=(i-last_i-1) \times h_i ansi?=(i?lasti??1)×hi?。
最后的答案輸出: a n s i + 1 ans_i+1 ansi?+1。
完成!
Code
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 2e5 + 10;
int n,a[N],maxn[N],ans[N],last[N];
int F(int x,int y)
{if(a[x] >= y) return x;if(x == last[x]) return x;return F(last[x],y);
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);//freopen(".in","r",stdin);//freopen(".out","w",stdout);cin >> n;for(int i = 1;i <= n;i++){cin >> a[i];maxn[i] = max(maxn[i - 1],a[i]);if(a[i] == maxn[i])last[i] = i;else if(a[i] > a[i - 1])last[i] = F(i - 1,a[i]);elselast[i] = i - 1;}for(int i = 1;i <= n;i++){if(a[i] == maxn[i]){cout << ((ans[i] = a[i] * i) + 1) << " ";}else{ans[i] = ans[last[i]] + a[i] * (i - last[i]);cout << ans[i] + 1 << " ";}}return 0;
}