傳送門
1.因為一點小失誤,一直沒調出來,有點可惜
2.實際上有點lis的感覺,我們設d(i
)d(i)
d(i)
表示從i
ii開始的攻擊力最大值,b[i
]b[i]
b[i]
為位置i
ii的攻擊力,那麼可以得出:
d (i
)=ma
x(d(
i),b
[i]+
d(j)
),
j>id(
i)=m
ax(d
(i),
b[i]
+d(j
)),j
>
i考慮從後向前遞推,那麼我們只需要求出每乙個位置前面已經更新的位置中,滿足生命值之差的絕對值小於等於d
dd的最大攻擊力轉移
考慮使用線段樹維護,下標的含義是生命值,樹的權值為最大攻擊力,那麼每次只需求出區間[ma
x(a[
i]−d
,1),
a[i]
+d
)[max(a[i]-d,1),a[i]+d)
[max(a
[i]−
d,1)
,a[i
]+d)
中的最值,然後更新生命值a[i
]a[i]
a[i]
的權值。只需單點修改和區間查詢的最值線段樹
因為a [i
]+d≤
2e
5a[i]+d \leq 2e^5
a[i]+d
≤2e5
,因此我們要在這個最大範圍內建樹維護
ps:本題從前向後和從後向前遞推均可以
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define lowbit
(x)(x&
(-x)
)#define mkp
(x,y)
make_pair
(x,y)
#define mem
(a,x)
memset
(a,x,sizeof a)
;typedef long
long ll;
typedef long
double ld;
typedef unsigned long
long ull;
typedef pair<
int,
int>
p;const
double eps=
1e-8
;const
double pi=
acos(-
1.0)
;const
int inf=
0x3f3f3f3f
;const ll inf=
1e18
;const
int mod=
1e9+7;
const
int maxn=
2e5+10;
int a[maxn]
,b[maxn]
;ll dp[maxn]
;ll tree[maxn<<2]
;inline ll max
(int a,
int b)
void
build
(int i,
int l,
int r)
int mid=
(l+r)
>>1;
int k=i<<1;
build
(k,l,mid)
;build
(k|1
,mid+
1,r)
; tree[i]
=max
(tree[k]
,tree[k|1]
);}void
update
(int i,
int l,
int r,
int x,ll y)
int mid=
(l+r)
>>1;
int k=i<<1;
if(x<=mid)
update
(k,l,mid,x,y)
;else
update
(k|1
,mid+
1,r,x,y)
; tree[i]
=max
(tree[k]
,tree[k|1]
);}ll query
(int i,
int l,
int r,
int x,
int y)
intmain()
cout
}
B 卡牌遊戲 IV
b 卡牌遊戲 iv 蒜頭君在玩一種卡牌遊戲,他有 n 張卡牌,每張卡牌上寫著兩個正整數 ai,bi ai 表示這張卡牌的能量值,bi表示這張卡牌的魔法值。他準備一張一張打出這 n張卡牌,每張卡牌會對敵人造成的傷害是這張卡牌的能量值乘魔法值。但是蒜頭君覺得這樣把這 n張卡牌都出完對敵人造成的傷害之和還...
卡牌遊戲II bfs
有n張卡片,上面印著整數a1,a2,a3 an,可以選取其中任意數量張卡片,求出乙個和s,共有2 n 1個和 要求出最小的前n個和分別是多少 題目包含多組資料。輸入的每一行有乙個整數t 1 t 5 代表有t組資料 對於每組資料分為兩行 第一行有兩個整數n,k 其中1 n 200000,1 k min...
卡牌遊戲期望
題目描述好像有點問題。應該是n種卡牌。m種稀有卡牌,且抽出不放回。對於求期望來說,相比之下我們更容易求出概率。而對於此類題目 期望往往 1 概率 暫時這麼理解的 而期望具有可加性。把所有稀有卡牌都抽一遍的期望 每次抽得乙個稀有卡牌的期望的和。至少抽出k張稀有卡牌的期望 抽出k張每次抽的乙個稀有卡牌的...