动态维护一个非严格单调递增队列即可
这样队列尾就是最大值
每个元素只可能进出队列各一次
O(n)
#include<stdio.h>
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))
using namespace std;
const int INF = 1e9+7;
const int inf=INF;
struct S{
deque<int>que;//原数据
deque<int>incrQue;//非严格单调递增队列
void init(){
que.clear();
incrQue.clear();
}
void push_back(int x){
que.push_back(x);
if(incrQue.empty()||x>=incrQue.back()){
incrQue.push_back(x);
}
}
void push_front(int x){
que.push_front(x);
while(!incrQue.empty()&&incrQue.front()<x){
incrQue.pop_front();
}
incrQue.push_front(x);
}
void pop_back(){
if(que.back()==incrQue.back()){
incrQue.pop_back();
}
que.pop_back();
}
int maxVal(){
return incrQue.back();
}
int size()const{
return que.size();
}
}myStack;
int main(){
//freopen("/home/lu/code/r.txt","r",stdin);
//freopen("/home/lu/code/w.txt","w",stdout);
int n,A,B,C,x0,a,b,MOD;
while(~scanf("%d%d%d%d%d%d%d%d",&n,&A,&B,&C,&x0,&a,&b,&MOD)){
myStack.init();
int ans=0;
int ta,tb;
for(int i=1;i<=n;++i){
int xi=((ll)x0*a+b)%MOD;
if(xi%(A+B+C)<A||myStack.size()<=1){
ta=0;
tb=xi;
}
else{
if(A<=xi%(A+B+C)&&xi%(A+B+C)<A+B){
ta=1;
tb=xi;
}
else{
if(A+B<=xi%(A+B+C)){
ta=2;
}
}
}
switch (ta) {
case 0:
myStack.push_back(tb);
break;
case 1:
myStack.push_front(tb);
break;
case 2:
myStack.pop_back();
default:
break;
}
ans=(ans+myStack.maxVal())%inf;
x0=xi;
}
printf("%d\n",ans);
}
return 0;
}