现在有一个栈,初始为空。接下来有若干次操作,每次可能向栈顶 push 一个正整数,也可能 pop 掉 栈顶元素。 你需要在每次操作之后计算出栈内所有元素的最大值。如果栈为空则认为此时最大值是 0。 为了避免输入文件过大,所有操作会使用 rng61 算法生成。同时为了避免输出文件过大,你只需要 输出一个数:表示每次操作之后的答案与下标乘积的异或和。
输入格式
第一行包含一个整数 T,表示测试数据的组数。 接下来依次描述 T 组测试数据,为了减少读入量,采用如下的方式来给出数据。
对于每组测试数据:一行给出了 7 个整数依次为 n, p, q, m, SA, SB, SC。其中 n 表示总的操作次数, 你的程序可以使用如下所示的 C++ 代码生成所有的操作。
( 代码见原题面) 在这份代码中,PUSH(v) 表示向栈中插入一个新的元素,它的值为 v。POP() 表示弹出栈顶元素;如 果当前栈为空,则什么也不操作(即:没有东西可以弹出)。
输出格式 对于每组测试数据,输出一行信息 "Case #x: y"(不含引号),其中 x 表示这是第 x 组测试数据, y 等于 n ⊕ i=1 (i · ai),其中 ai 表示第 i 次操作后的答案,⊕ 表示异或和。
解题思路;可以用数组模拟栈的操作,在栈顶,存放栈中最大的元素;
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<math.h>
#include<time.h>
#include<vector>
#include<set>
#include<map>
#include<stack>
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a))
#define lowbit(a) a&(-a)
#define shortime(a) std::ios::sync_with_stdio(a);
using namespace std;
const LL inf=1e9+7;
//long long cmp(node a,node b){ if(a.x==b.x) return a.r>b.r;return a.x>b.x;}
int maxn (int a,int b,int c){return max(max(a,b),max(b,c));}
int a[5000005];
int n, p, q, m;
unsigned int SA, SB, SC;
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;
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1; i<=t; i++)
{
mem(a,0);
scanf("%d%d%d%d%u%u%u", &n, &p, &q, &m, &SA, &SB, &SC);
long long sum=0;
int num=0;
for(int j=1;j<=n;j++)
{
if(rng61() % (p + q) < p)
{
num++;
a[num]=rng61()%m+1;
a[num]=max(a[num],a[num-1]);
}
else
{
if(num>0) num--;
}
sum=sum^(1LL*j*a[num]);
}
printf("Case #%d: %lld\n",i,sum);
}
return 0;
}