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;
}

 

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