D. Riverside Curio
time limit per test 1second
memory limit per test 256megabytes
Arkady decides to observe a river for n consecutivedays. The river's water level on each day is equal to some real value.
Arkady goes to the riverside each dayand makes a mark on the side of the channel at the height of the water level,but if it coincides with a mark made before, no new mark is created. The waterdoes not wash the marks away. Arkady writes down the number of marks strictlyabove the water level each day, on the i-th day this value is equal to mi.
Define di as the number of marks strictly underthe water level on the i-th day. You are to find out the minimum possible sum of di over all days.There are no marks on the channel before the first day.
Input
The first line contains a singlepositive integer n (1 ≤ n ≤ 105) — thenumber of days.
The second line contains n space-separatedintegers m1, m2, ..., mn (0 ≤ mi < i) — the number of marks strictly above the water on each day.
Output
Output one single integer — the minimum possible sum of the number of marks strictly below the water level among all days.
Examples
Input
Copy
6
0 1 0 3 0 2
Output
6
Input
5
0 1 2 1 2
Output
1
Input
5
0 1 1 2 2
Output
0
Note
In the first example, the following figure shows an optimal case.
Note that on day 3, a new mark should be created because if not, there cannot be 3 marks above water on day 4. The totalnumber of marks underwater is 0 + 0 + 2 + 0 + 3 + 1 = 6.
In the second example, the following figure shows an optimal case.
【题意】
有一个人每天会去观察一条河流的水位,每次在当前水位上画一条线(如果重复则不画)
现在告诉你他每天去看时,当前水位的上方(严格大于)画了几条线。
问每天去看时,当前水位的下方(严格小于)画线条数d[i]总和的最小值。
【思路】
我们用sum[i]表示,前i天一共画了多少条线,由于sum[i]=d[i]+a[i]+1,那么最小化sigma(d[i])就转化为了最小化sigma(sum[i)。
于是我们尽量使得每个sum[i]小,由于sum[i]必须满足:
- sum[i]>=max(sum[i-1],a[i]+1)
- sum[i]>=sum[i+1]-1 每天最多画一条线
条件1很好满足,为了满足条件2,我们需要从最后一天开始往上更新即可
然后再正向更新一下,保证sum[i]>=sum[i-1]
最后代入公式即可。
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
typedef long long ll;
const int maxn = 100005;
const ll mod = 1e9+7;
const ll INF = 1e18;
const double eps = 1e-6;
int n;
ll a[maxn];
ll sum[maxn];
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%lld",&a[i]);
ll now=0;
for(int i=n-1;i>=0;i--)
{
now=max(now-1,a[i]+1);
sum[i]=now;
}
ll ans=sum[0]-a[0]-1;
for(int i=1;i<n;i++)
{
sum[i]=max(sum[i],sum[i-1]);
ans+=(sum[i]-(a[i]+1));
}
printf("%lld\n",ans);
}