C. C. Blog

Security Research, Algorithm and Data Structure

51Nod 1403 有趣的堆栈

Problem

大家都熟悉堆栈操作。一个堆栈一般有两种操作,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 这两种记录方法可以互相转化,我们的问题是,给定第二种记录方法的序列,请求出第一种记录方法的序列。

Solution

第i个位置变成i,然后扫到几,就在他前面几个数上加1,我也不知道为啥,推出来的。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include<stdio.h>
#include<set>
//#include<iostream>
#include<stack>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
typedef long long ll;
typedef long double ld;
typedef double db;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//using namespace std;
const int mod=998244353;
int mo(ll a,int p){
return a>=p?a%p:a;
}

inline int rd() {
int x = 0, f = 1;
char ch;
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return f * x;
}
int n,x;
int f[1000020];
char pbuf[100000],*pp=pbuf;
void push(const char c) {
if(pp-pbuf==100000) fwrite(pbuf,1,100000,stdout),pp=pbuf;
*pp++=c;
}
void write(int x) {
static int sta[35];
int top=0;
do{sta[top++]=x%10,x/=10;}while(x);
while(top) push(sta[--top]+'0');
push(' ');
}
int main(){
//io_opt;
n=rd();
for(register int i=1;i<=n;i++){
x=rd();
if(x){
f[i-x-1]++;
f[i-1]--;
}
}
register int las=0;
for(register int i=1;i<=n;i++){
las=1+las+f[i-1];
write(las);
}
fwrite(pbuf,1,pp-pbuf,stdout);
return 0;
}



  • 本文作者: CCWUCMCTS
  • 本文链接: https://ccwucmcts.github.io/posts/15049/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!