大家都熟悉堆栈操作。一个堆栈一般有两种操作,push和pop。假设所有操作都是合法的并且最终堆栈为空。我们可以有很多方法记录堆栈的操作,
(1) 对每个pop操作,我们记录它之前一共有多少个push操作。
(2) 对每个pop操作,我们记录这个被Pop的元素曾经被压上了几个。
例如:操作push, push, pop, push, push, pop, push, pop, pop, pop
用第一种方法 记录为 2, 4, 5, 5, 5
用第二种方法 记录为 0, 0, 0, 2, 4
这两种记录方法可以互相转化,我们的问题是,给定第二种记录方法的序列,请求出第一种记录方法的序列。
Input
第一行一个整数n,表示序列的长度(0 < n <=1000000)
第二行n个整数,表示第二种方法的记录。
Output
一行,空格分隔的n个整数,表示第一种表示方法的序列。
Sample Input
5
0 0 0 2 4
Sample Output
2 4 5 5 5
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX =1e6+10;
int a[MAX]; //原始数据
int f[MAX]; //这个pop与上个pop间有几个push
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]==0) //push之后就是pop
f[i]=1; //两个pop之间有一个push
else
{
f[i-a[i]]++;
f[i] = 0;
}
}
int ans=0;
// for(int i=1;i<=n;i++)
// {
// printf("%d ",f[i]);
// }
// printf("\n");
for(int i=1;i<n;i++)
{
ans=ans+f[i];
printf("%d ",ans);
}
printf("%d\n",ans+f[n]);
}
return 0;
}