题意:
刚开始有一个空栈,我们可以对这个栈进行n次操作,每次操作之后返回栈中数字的最大值a[i],如果栈为空,那么则返回0,即a[i] = 0。。怎样对栈进行操作题目已经给出,需要求的是
思路:
直接模拟,刚开始队友可能想到线段树维护最大值
需要注意的是除了题目中描述的函数的变量类型不改为long long, 其他的变量类型全部变为long long
问题 :需要思考的是pop的时候是怎么维护最大值的?
答:用一个pre数组存储当前栈中的最大值
如果操作是push,我们很容易可以想到pre[top] = max(st[top],pre[top - 1]);
如果操作时pop, 就把top–,pop之后的最大值就是pre[top];
代码实现:
#include<cstdio>
#include<math.h>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<queue>
#include<deque>
#include<stack>
using namespace std;
#define Case int T;scanf("%d", &T);while(T--)
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 5e6 + 5;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
const double PI = acos(-1.0);
ll a[maxn];
ll st[maxn];
ll pre[maxn];
ll top = 0;
ll ans = 0;
ll n, p, q, m;
unsigned int SA, SB, SC;
int tot;
unsigned int rng61(){ //题目要求输入
SA ^= SA << 16;
SA ^= SA >> 5;
SA ^= SA << 1;
unsigned int t = SA;
SA = SB;
SB = SC;
SC ^= t ^ SA;
return SC;
}
void PUSH(unsigned int x){//插入
st[++top] = x;
pre[top] = max(st[top],pre[top - 1]);
}
void POP(){//删除
if(top == 0) return ;
else top--;
}
void gen(){//题目要求输入
scanf("%lld%lld%lld%lld%u%u%u",&n,&p,&q,&m,&SA,&SB,&SC);
for(int i = 1;i <= n;i++){
if(rng61() % (p + q) < p){
PUSH(rng61() % m + 1);
}
else{
POP();
}
if(top == 0) continue;
ans = ans ^ (i * pre[top]);//答案求解
}
}
int main(){
int t;
scanf("%d",&t);
int cnt = 0;
while(t--){
top = 0;
ans = 0;
gen();
printf("Case #%d: %lld\n",++cnt,ans);
}
return 0;
}