【思维】单调栈+dp——2020 联想杯 G

/*
用一个递增单调栈维护b[1..i-1]
将bi更新进单调栈,栈顶第二个元素+1 到bi区间的最小值都改成bi,然后求个和就行 
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define mod 998244353
#define N 10000007

ll n,p,x,y,z,b[N],ans[N],sum[N];
ll getnxt(int i){
    return (x*ans[i]%p+b[i]*y%p+z)%p;
}

int main(){
    cin>>n>>p>>x>>y>>z>>b[1];
    ans[1]=b[1];sum[1]=b[1];
    
    stack<int>stk; 
    stk.push(1);
    for(int i=2;i<=n;i++){
        b[i]=getnxt(i-1);
        while(stk.size()>0 && b[stk.top()]>=b[i])
            stk.pop();
        int L;
        if(stk.size())L=stk.top();
        else L=0;
        stk.push(i);
        sum[i]=(sum[L]+b[i]*(i-L)%mod)%mod;
        ans[i]=(ans[i-1]+sum[i])%mod;
    }
    ll anss=0;
    for(int i=1;i<=n;i++)anss^=ans[i];
    cout<<anss<<'\n';
}

 

posted on 2020-05-30 21:34  zsben  阅读(169)  评论(0编辑  收藏  举报

导航