Riverside Curio(CF Round #472 D div2 思维水题)

D. Riverside Curio
time limit per test
1 second

Arkady decides to observe a river for n consecutive days. The river's water level on each day is equal to some real value.

Arkady goes to the riverside each day and 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 water does not wash the marks away. Arkady writes down the number of marks strictly above the water level each day, on the i-th day this value is equal to mi.

Define di as the number of marks strictly under the 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 single positive integer n (1 ≤ n ≤ 105) — the number of days.

The second line contains n space-separated integers 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
Copy
5
0 1 2 1 2
Output
1
Input
Copy
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 total number of marks underwater is 0 + 0 + 2 + 0 + 3 + 1 = 6.

In the second example, the following figure shows an optimal case.

题意

每天在当前水位刻一条线,如果这个水位上以前已经刻过了就不用重复再刻,输入的m[ ]是每天水位以上有多少条刻线(第一天开始的时候保证是没刻线的),问n天里水位以下刻线的总数的最小值。


思路

第i天刻线总条数为num[ ]。


首先,要保证你的方案能满足输入的这组数据,所以第i天刻线总条数num[i]为max(m[i+1],m[i]+1)。


其次,刻线必然随天数越来越多,刻线条数必然越来越多,即num[i]>=num[j](i>j)。


最后一点,相邻两天刻线条数最多相差1,如果num[i]+1<num[i+1] , num[i]=num[i+1]-1。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

const int MAX = 1e5+100;
const int INF = 1e9+7;

int n;
int m[MAX];
int num[MAX];

int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&m[i]);
    num[n-1]=m[n-1]+1;
    for(int i=n-2;i>=0;i--)
    {
        num[i]=max(m[i+1],m[i]+1);
    }
    for(int i=1;i<n;i++)
    {
        if(num[i]<num[i-1])
            num[i]=num[i-1];
    }
    for(int i=n-2;i>=0;i--)
    {
        if(num[i+1]-num[i]>1)
            num[i]=num[i+1]-1;  
    }
    long long ans=0;
    for(int i=1;i<n-1;i++)
    {
        ans+=1LL*(num[i]-m[i]-1);
    }
    ans+=1LL*(num[n-1]-m[n-1]-1);
    printf("%lld\n",ans);
    return 0;
}
    
/*
样例:

100

0 1 2 2 3 0 1 5 6 6 0 0 8 7 1 9 9 4 10 11 
12 2 12 12 12 12 9 13 14 8 15 15 15 19 15 7 17 17 18 19 
9 10 21 0 22 9 2 24 24 4 24 7 25 14 5 8 28 
29 30 31 31 31 0 3 15 31 8 33 6 35 35 35 36 36 37 37 38 
39 28 0 2 23 41 9 9 0 6 25 41 41 12 42 43 43 36 44 51 45 43 4

*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值