暑期訓練1 Gym - 102623G Gentle Jena 單調棧
阿新 • • 發佈:2020-08-19
動態往序列末尾加數字,每次新增完求序列內所有子區間的RMQ(最小值)之和,強制線上求法,求線性做法。
1.考慮某位置上的數x作為區間最小值出現的次數,一旦插入了一個比x大的數,x的貢獻就不再變化。
2.當插入一個數時,只有從末尾往前單調遞增的數的貢獻才會變化,容易想到用一個單調棧維護。
首先,如果這個數已經被彈出棧了,那麼不需要考慮;
而對於棧內的數字,假設它的下標為xi,而它下面的一個數的下標為x i -1,那麼根據單調棧的性質,在xi - x i -1中不存在比當前數更小的數,因此每次新加入一個數時
以[xi - 1, xi ]中任意一個數為區間起點,都可以以新數為區間終點構成新的區間,因此它的貢獻值會增加。
struct ST { ll val; int idx; }; ST st[10000005]; int n; ll x, y, z, p, b; ll res, pre; int main() { n = readint(); p = readll(); x = readll(); y = readll(); z = readll(); b = readll(); ll now = 0; int top = 0; for (int i = 1; i <= n; i++) { while (top > 0&& b < st[top].val) { pre = (pre - st[top].val * (st[top].idx - st[top - 1].idx) % MOD + MOD) % MOD; top--; } now += b * (i - st[top].idx) % MOD + pre, now %= MOD; res ^= now; pre += b * (i - st[top].idx) % MOD; pre %= MOD; st[++top].val = b; st[top].idx = i; b = (x * now + y * b + z) % p; } Put(res); }