Gentle Jena【2020 年 “联想杯” G题】【笛卡尔树/单调栈】

题目链接


  题意:给你N个数,b[1]~b[n],但是不是一开始就给出的,一开始只给出b[1],后面的都是通过前面的情况得到的,给出p、x、y、z和b[1],p、x、y、z都是涉及b[2]~b[n]怎样来的,我们定义一个B(S),

还有,而其中A(i)是代表了B(S)( |S| == i 时候)的权值大小,我们想知道答案:

自然1e7的数据必然是O(N)的做法了。

  可以考虑一个数b[pos]起作用的区间是[l, pos, r]也就是找到lef[pos]是左边第一个比他小的数的位置和右边第一个比它小的数的位置,它起到的贡献可以考虑成(pos - lef) * (rig - pos),我们可以只考虑(pos - lef)这段,给pos~rig-1这段全都加上一个(pos - lef)。简单的差分的作用了,我们可以直接维护这个。

  维护一个单调递增的栈,我们可以确定lef和rig。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
typedef __uint128_t bigint;
const ull mod = 998244353;
const int maxN = 1e7 + 7;
int N, Stop = 0;
ll b[maxN], p, x, y, z, A[maxN];
struct node
{
    ll pos, val;
    node(ll a=0, ll b=0):pos(a), val(b) {}
} Stap[maxN];
int main()
{
    scanf("%d%lld%lld%lld%lld%lld", &N, &p, &x, &y, &z, &b[1]);
    ll each_sum = 0;
    for(ll i=1; i<=N; i++)
    {
        while(Stop && Stap[Stop].val >= b[i])
        {
            each_sum = (each_sum - Stap[Stop].val * (Stap[Stop].pos - Stap[Stop - 1].pos) % mod + mod) % mod;
            Stop--;
        }
        each_sum = (each_sum + b[i] * (i + mod - Stap[Stop].pos) % mod) % mod;
        Stap[++Stop] = node(i, b[i]);
        A[i] = (A[i - 1] + each_sum) % mod;
        b[i + 1] = (x * A[i] + y * b[i] + z) % p;
    }
    ll ans = 0;
    for(int i=1; i<=N; i++) ans ^= A[i];
    printf("%lld\n", ans);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章