Codeforces Round #446 (Div. 2) B 题

B. Wrath
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Input

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.

Output

Print one integer — the total number of alive people after the bell rings.

Examples
input
4
0 1 0 10
output
1
input
2
0 0
output
2
input
10
1 1 3 0 0 0 2 1 0 3
output
3
Note

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;
}



posted @ 2017-11-18 14:58  Sizaif  阅读(125)  评论(0编辑  收藏  举报