題目傳送門
給出一種元素 \((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 因此,我們考慮將雙端佇列拆成兩棧分別維護左端和右端。...