打怪(CDQ分治 斜率優化)

2021-10-04 10:52:49 字數 2927 閱讀 1503

敵方有 n

nn 只怪,每只的攻擊力為 a

ia_i

ai​,血量為 d

id_i

di​。

我方只有乙隻攻擊力為 b

bb 的怪。

每回合戰鬥的流程為:

求所受傷害最小值。

顯然我方只有在連續攻擊乙隻怪致死後,才會換下乙隻。設第 i

ii 只怪需要被連續攻擊:

c i=

⌊di−

1b⌋+

1c_i=\lfloor \frac \rfloor +1

ci​=⌊b

di​−

1​⌋+

1若沒有秒殺的操作,只考慮我方的攻擊順序。

則第 i

ii 只怪排在第 j

jj 只之後,當且僅當:

c i∗

aj

>cj

∗a

ic_i*a_j>c_j*a_i

ci​∗aj

​>cj

​∗ai

​ 於是我們按照這一關鍵字排序即可。

現考慮秒殺操作。若僅秒殺乙隻怪 ,則傷害值會減小:

e i=

ai∑j

=1i−

1cj+

ai(c

i−1)

+ci∑

j=i+

1naj

e_i=a_i\sum_^ c_j+a_i(c_i-1)+c_i\sum_^a_j

ei​=ai

​j=1

∑i−1

​cj​

+ai​

(ci​

−1)+

ci​j

=i+1

∑n​a

j​考慮若確定秒殺第 i

ii 只怪,再秒殺第 j

jj 只怪比秒殺第 k

kk 只怪優(其中j

jj,k

kk< i

ii 且 c

jc_j

cj​>c

kc_k

ck​),當且僅當:

e i+

ej−a

i∗cj

>ek

+ei−

ai∗c

ke_i+e_j-a_i*c_j>e_k+e_i-a_i*c_k

ei​+ej

​−ai

​∗cj

​>ek

​+ei

​−ai

​∗ck

​化簡得:

a

i>ej

−ekc

j−ck

a_i> \frac

ai​>cj

​−ck

​ej​

−ek​

​這是乙個斜率優化模型(不懂的話右轉斜率優化),顯然可以用李超樹動態維護,但我不會,我們以c為橫座標,e為縱座標的座標軸上,有可能成為最優決策的只有上凸的點。

維護乙個單調遞減的上凸殼即可。

但注意到 a

ia_i

ai​ 和 c

jc_j

cj​ 無序。

考慮用 cdq

cdqcd

q 分治處理。

對於區間 [l,

r]

[l,r]

[l,r

],將 [l,

mid]

[l,mid]

[l,mid

] 和 [mi

d+1,

r]

[mid+1,r]

[mid+1

,r] 分別按 c

cc 和 a

aa 排序,即可進行斜率優化。

複雜度 o(n

log2

n)

o(nlog^2n)

o(nlog

2n)。

**:

//#pragma gcc optimize(2)

//#pragma gcc optimize(3, "ofast", "inline")

#include

using namespace std;

typedef

long

long ll;

typedef

unsigned

long

long ull;

typedef pair<

int,

int> pii;

const

int n=

1e6+5;

const ll mod=

998244353

;const

double eps=

1e-5

;const

double pi=

acos(-

1);#define ls p<<1

#define rs p<<1|1

struct node

a[n]

;int q[n]

;bool cmp

(node x,node y)

bool cmpy

(node x,node y)

bool cmpx

(node x,node y)

ll ans,sum;

void

cdq(

int l,

int r)

for(

int i=mid+

1;i<=r;i++)}

intmain()

sort

(a+1

,a+1

+n,cmp)

;for

(int i=

1;i<=n;i++

) ans=sum;

cdq(

1,n)

; cout

}

CDQ分治與斜率優化DP 學習筆記

我們知道當斜率優化dp中的點的x座標不單調時,需要splay來維護凸殼,但是 量比較大,容易寫掛。我們還有一種神奇的做法 cdq分治。先把n個狀態排成乙個序列。考慮乙個分治過程solve l,r 每次分成 l,mid mid 1,r 兩部分。顯然對於fi只和1 i 1有關,所以我們solve l,m...

CDQ分治概述

log l og 的時間把它變成離線問題。正好有些題目的離線問題是比較簡單的。具體是什麼意思呢?我們對於每一層分治,只考慮前一半對於後一半的影響,然後在每個詢問當中記錄下來影響。最後把所有影響合併就可以得到每乙個詢問的答案。舉個例子 區間修改區間查詢。首先,在時間軸上離線分治。每一層分治後把詢問和查...

CDQ分治總結

cdq這個東西嘛,說容易其實也很容易,說難其實也有些難,但只要細細品味,定能發現其中的真理的!那真理,也會像蝴蝶一般,破蛹而出,化身為一道亮麗的風景線。題記。咳咳,閒話就講到這裡了,切入正題。首先我們來了解一下cdq分治這個東東。cdq分治,他的常數小,但必須離線操作the most importa...