Hands that shed innocent blood!
There are n guilty people in a line, the i-th of them holds a claw with length Li. The bell rings and every person kills some of people in front of him. All people kill others at the same time. Namely, the i-th person kills the j-th person if and only if j < i and j ≥ i - Li.
You are given lengths of the claws. You need to find the total number of alive people after the bell rings.
The first line contains one integer n (1 ≤ n ≤ 106) — the number of guilty people.
Second line contains n space-separated integers L1, L2, ..., Ln (0 ≤ Li ≤ 109), where Li is the length of the i-th person's claw.
Print one integer — the total number of alive people after the bell rings.
4 0 1 0 10
1
2 0 0
2
10 1 1 3 0 0 0 2 1 0 3
3
In first sample the last person kills everyone in front of him.
【题意】
好理解 杀死前面的人, 问最后活下几个人, 最后一个人 一定活
【思路】
先把 i - li 算出来, 负值 赋值为1
从后面往前扫, 维护一个最小值, 前面的 i 如果比这个最小值 大 就一定死掉
【代码实现】
#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define S1(n) scanf("%d",&n)
#define SL1(n) scanf("%I64d",&n)
#define S2(n,m) scanf("%d%d",&n,&m)
#define SL2(n,m) scanf("%I64d%I64d",&n,&m)
#define Pr(n) printf("%d\n",n)
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MAXN=50005;
const int MAX=1<<22;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};
ll inv[maxn*2];
inline void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){ x=1; y=0; d=a; }else{ ex_gcd(b,a%b,d,y,x); y-=x*(a/b);};}
inline ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll ans=exgcd(b,a%b,x,y);ll temp=x;x=y;y=temp-a/b*y;return ans;}
inline ll lcm(ll a,ll b){ return b/gcd(a,b)*a;}
inline ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x)%MOD;x=(x*x)%MOD;}return res;}
inline ll inv_exgcd(ll a,ll n){ll d,x,y;ex_gcd(a,n,d,x,y);return d==1?(x+n)%n:-1;}
inline ll inv1(ll b){return b==1?1:(MOD-MOD/b)*inv1(MOD%b)%MOD;}
inline ll inv2(ll b){return qpow(b,MOD-2);}
int b[maxn];
int vis[maxn];
struct math_tree{
int n;
int a[MAX],Max[MAX],Min[MAX];
int tree[MAX];
void init(int N)
{
n=N;
for(int i=0;i<=N;i++)
Max[i]=-(Min[i]=INF);
}
void update(int k,int num)//单点更新
{
a[k]=num;
while(k<=n)
{
tree[k]+=num;
Min[k]=Max[k]=a[k];
int lk=k&(-k);
for(int i=1;i<lk;i<<=1)
{
Max[k]=max(Max[k],Max[k-i]);
Min[k]=min(Min[k],Min[k-i]);
}
k+=k&(-k);// lowbit(k)= k&(-k);
}
}
int Sum(int k)
{
int sum=0;
while(k)
{
sum+=tree[k];
k-=k&-k;
}
return sum;
}
int Get_Sum(int x,int y)
{
return Sum(y)-Sum(x-1);
}
int Qmax(int x,int y)//[x,y]区间最大值
{
int ans=-INF;
while(y>=x)
{
ans=max(a[y], ans);
y--;
for(;y-(y&-y)>=x;y-=(y&-y))
ans=max(Max[y],ans);
}
return ans;
}
int Qmin(int x,int y)//[x,y] 区间最小值
{
int ans=INF;
while(y>=x)
{
ans=min(a[y],ans);
y--;
for(;y-(y&-y)>=x;y-=(y&-y))
ans=min(ans,Min[y]);
}
return ans;
}
}A;
int main()
{
int n;
while(~scanf("%d",&n))
{
int x;
A.init(n);
for(int i=1;i<=n;i++)
{
S1(x);
if(i-x<0)
b[i]=1;
else
b[i]= i-x;
A.update(i,b[i]);
}
int ans=1;
for(int i=n-1;i>=1;i--)
{
// printf("%d\n",A.Qmin(i,n));
if(i<A.Qmin(i+1,n))
{
ans++;
// printf("**\n");
}
}
printf("%d\n",ans);
}
return 0;
}