4306 貪玩藍月

2021-10-02 20:14:58 字數 1592 閱讀 4134

題目描述

《貪玩藍月》是目前最火爆的網頁遊戲。在遊戲中每個角色都有若干裝備,每件裝備有乙個特徵值 w

ww 和乙個戰鬥力 v

vv 。在每種特定的情況下,你都要選出特徵值的和對 p

pp 取模後在一段範圍內的裝備,而角色死亡時自己的裝備會爆掉。每個角色的物品槽可以看成乙個雙端佇列,得到的裝備會被放在兩端,自己的裝備爆掉也會在兩端被爆。

現在我們有若干種事件和詢問,如下所示: 題解

考慮只加不刪的話,那就是普通的 dp

\text

dp ,即 f[i

][j]

f[i][j]

f[i][j

] 表示前 i

ii 個物品,特徵值的和模 p

pp 為 j

jj 的最大戰鬥力和,然後揹包轉移即可

考慮有刪數的話,就上線段樹分治即可,於是就又是只有加數的了,效率: o(m

plog

m)

o(mplogm)

o(mplo

gm)

**

#include

#define ll long long

using

namespace std;

const

int n=

2e5+5;

int m,p,b[n]

,u[n]

,v[n]

,g[n]

;ll f[30]

[500

],f[

500]

;struct oa[n]

;vectorg[n]

;char ch[9]

;#define ls k<<1

#define rs k<<1|1

#define mid ((l+r)>>1)

void

upd(

int k,

int l,

int r,

int l,

int r,o v)

if(mid>=l)

upd(ls,l,mid,l,r,v);if

(midupd(rs,mid+

1,r,l,r,v);}

void

qry(

int k,

int l,

int r,

int d)

if(l==r)

return;}

else

}int

main()

else

if(ch[0]

=='q'

) g[i]=1

,scanf

("%d%d"

,&u[i]

,&v[i]);

else

}for

(int i=l;i<=r;i++

)upd(1

,1,m,b[i]

,m,a[i]);

for(

int i=

1;i) f[0]

[i]=

-2e18

;qry(1

,1,m,0);

return0;

}

貪玩 van 藍月

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

題解 貪玩藍月

題目傳送門 給出一種元素 u,w 表示它的特徵值為 u 戰鬥力為 w 現在給你乙個雙端佇列,維護該元素,支援兩端加點刪點,以及查詢特徵值之和 pmod p 在 l,r 之內的戰鬥力之和最大的子串行。設操作次數為 m 則保證 m le 5 times 10 4,p le 500 因為懶 菜 得 不 一...

雅禮集訓 2018 Day10 貪玩藍月

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