題解 貪玩藍月

2022-05-01 19:51:10 字數 1400 閱讀 7956

題目傳送門

給出一種元素 \((u,w)\) ,表示它的特徵值為 \(u\) ,戰鬥力為 \(w\) 。現在給你乙個雙端佇列,維護該元素,支援兩端加點刪點,以及查詢特徵值之和\(\pmod p\) 在 \([l,r]\) 之內的戰鬥力之和最大的子串行。

設操作次數為\(m\),則保證 \(m\le 5\times 10^4,p\le 500\)

因為懶(菜)得(不)一(可)批(言),所以我並沒有對其進行實現,所以下面的純屬口胡。不難看出每個元素出現是有時間的,所以我們就可以使用線段樹分治,直接dp即可。時間複雜度 \(\theta(mp\log m)\),但是實際上有乙個 \(\dfrac\) 的常數,應該不會很慢。

我們發現,我們其實可以用兩個棧來維護這個雙端佇列,乙個維護一邊,從中間斷開。然後如果乙個棧刪沒了就直接暴力重構把拆分點設為另乙個的中間。於是問題就是如何合併兩個棧裡面的答案,其實我們發現如果我們確定在乙個棧裡面我們特徵值的多少,那麼,餘數的範圍我們也固定了,於是,我們就可以區間查詢\(\max\)即可,這個可以用單調佇列、st表、線段樹做。

時間複雜度加點刪點均攤是 \(\theta(p)\) (維護dp值),合併如果是單調佇列就是 \(\theta(p)\) ,另外兩種就是 \(\theta(p\log p)\),總時間複雜度就是 \(\theta(mp)/\theta(mp\log p)\) 的。

#include using namespace std;

#define pii pair#define int register int

#define maxn 50005

#define maxm 505

pii t[2][maxn];//儲存的是

int mod,inf,top[2],f[2][maxn][maxm],st[maxn][20];

template inline void chkmax (t &a,t b)

void ins (bool k,int now,pii p)

void del (bool k)

int querymax (int l,int r)

int query (int l,int r)

return ans < 0 ? -1 : ans;

}template inline void read (t &t)while (c >= '0' && c <= '9') t *= f;}

template inline void read (t &t,args&... args)

template inline void write (t x)if (x > 9) write (x / 10);putchar (x % 10 + '0');}

signed main();while (n --> 0)

return 0;

}

4306 貪玩藍月

題目描述 貪玩藍月 是目前最火爆的網頁遊戲。在遊戲中每個角色都有若干裝備,每件裝備有乙個特徵值 w ww 和乙個戰鬥力 v vv 在每種特定的情況下,你都要選出特徵值的和對 p pp 取模後在一段範圍內的裝備,而角色死亡時自己的裝備會爆掉。每個角色的物品槽可以看成乙個雙端佇列,得到的裝備會被放在兩端...

貪玩 van 藍月

最窄的題目描述。這是不可能有的 首先需要發現乙個性質,如果現在已經求出k的答案,那麼k 2的答案序列就一定是在k的答案序列中插入兩個 可以是末尾與開頭 數所得到,至於為什麼,其實我也不知道,那麼考慮k 2的轉換,考慮cdq 假設對於k,在區間l mid選了k1個點,mid 1 r選了k2個點 那麼對...

雅禮集訓 2018 Day10 貪玩藍月

點這裡看題目。離線的話,我們顯然可以 線段樹分治 dp 時間複雜度大概是 o m log 2m mp 顯然我們需要乙個 dp 去維護答案,這裡不再贅述。考慮我們直接處理的難點之一是雙端佇列兩段可操作,而一端可操作的結構,棧,就可以簡單地維護 dp 因此,我們考慮將雙端佇列拆成兩棧分別維護左端和右端。...