description
度度熊在玩乙個叫做「打怪獸」的遊戲。
遊戲的規則是這樣的。
度度熊一開始會有乙個初始的能量值。每次遇到乙個怪獸,若度度熊的能量值≥ 怪獸的能量值並且度度熊剩餘血量≥怪獸的攻擊力,那麼怪獸將會被打敗,度度熊的能量值增加1,度度熊的血量減少該怪獸的攻擊力,否則度度熊死亡(度度熊的血量剛好減到0時並不會死亡,還能繼續戰鬥),遊戲結束。
若怪獸全部打完,遊戲也將會結束。
共有n個怪獸,由於度度熊比較弱,它一開始只有1點能量值。
n個怪獸排列隨機,也就是說共有n!種可能,度度熊想知道結束時它能量值的期望。
注意這裡怪獸的編號是從1開始到編號n為止且編號為i的怪獸能量值為i-1。
由於小數點比較麻煩,所以你只需要輸出期望*n!關於1000000007取模後的值就可以了!
在樣例中有5個怪獸,它們的能量分別為0,1,2,3,4,其中每個怪獸的攻擊力都為1。
input
多組資料。對於每一組資料:
第一行兩個數n,m表示有n只怪獸,度度熊的初始血量(1<=n<=500000,1<=m<=10^9)。
接下來一行n個數ai表示編號為i的怪獸的攻擊力(0<=ai<=m)。
output
一行表示答案。
sample input
5 4
1 1 1 1 1
sample output
solution令
num[
i]為至少乾掉
i 只怪獸的方案數,則乾掉
i只怪獸的方案數為nu
m[i]
−num
[i+1
] 進而
ans=
∑i=1
n−1i
⋅(nu
m[i]
−num
[i+1
])+n
um[n
]=∑i
=1nn
um[i
] 考慮求nu
m[i]
,給怪獸編號為
0 ~n−
1,那麼第
i 只怪獸能量為
i攻擊力為ai
,如果要乾掉
i 個怪獸,那麼0~
i−1 這
i 個怪獸中至少要乾掉i−
1個,由於第
i 次乾掉的怪獸其編號最多是
i,故我們考慮編號為
0 ~
i的怪獸即可
1 .若m−
∑j=0
i−1a
j≥0且
m−∑j
=0ia
j≥0 ,那麼前i+
1 只怪獸都可以乾掉,第
1 次可以從前兩個中選乙個乾掉,第
2次可以從前三個中(除去第一次被乾掉的還剩兩個)選乙個乾掉,第
i 次可以從前i+
1個中(除去前i−
1 次乾掉的還剩兩個)選乙個乾掉,故從前i+
1 個怪獸中選出
i 個乾掉方案數是2i
,剩下的n−
i 個怪獸可以隨便放,總方案數2i
⋅(n−
i)!
2.若m−
∑j=0
i−1a
j≥0且
m−∑j
=0ia
j<
0 ,那麼前i+
1 只怪獸不能像第
1 種情況那樣每次隨便乾掉,如果要乾掉
i個,那麼就要有一些「大怪獸」不能被乾掉,否則完不成乾掉
i 只怪獸的任務,假設m−
∑j=0
iaj+
ak>=
0,說明如果不乾掉第
k 只怪獸的話剩下的
i只怪獸都可以乾掉,即可以乾掉編號為
0 ~k−
1和k+
1 ~
i 的這些怪獸,從0~
k−1 的這
k 只怪獸中選出k−
1只怪獸乾掉的方案數和第
1 種情況相同,方案數為bk
=2ma
x(注意k=
0 時方案數是1),剩下乙隻怪獸只能第
k 次乾掉,乾掉這
k只怪獸後能量值是k+
1 ,第k+
1 步就只能乾掉k+
1 ,第k+
2 步就只能乾掉k+
2 ,……,第
i 步只能乾掉
i,故乾掉編號為
0 ~k−
1和k+
1 ~
i 的這些怪獸的方案數為bk
,剩下的n−
i 只怪獸依舊可以隨便放,令su
m=∑k
=0i[
m−∑j
=0ia
j+ak
≥0]b
k ,則總方案數為su
m⋅(n
−i)!
3 .若m−
∑j=0
i−1a
j<
0,類似第
2 種情況,令su
m=∑k
=0i[
m−∑j
=0ia
j+ak
≥0]b
k,則總方案數為su
m⋅(n
−i)!
現在問題變成如何快速得到su
m ,即滿足m−
∑j=0
iaj+
ak≥0
的bk 之和,注意到隨著
i 的增大,m−
∑j=0
iaj是遞減的,所以滿足條件的
k 只會越來越少,第一次出現滿足條件的
k是在第
2 種情況發生時,而且顯然第
2種情況至多出現一次,之後滿足條件的
k 中,一些ak
值較小的會被淘汰掉,用優先佇列維護滿足條件的
k ,ak
值最小的在隊首,維護su
m 的值,在第
2 種情況出現時把所有滿足條件的
k值放入優先佇列中並累加bk
的值得到su
m ,之後都是第
3 種情況,每次從隊首不斷取出不滿足條件的
k值,把bk
值從su
m 中減掉,這樣每個
k 值入隊一次出隊一次,每次計數是o(
1)的,總時間複雜度是o(
nlog
n)
注意上面只求了nu
m[1]
~num
[n−1
] ,對於nu
m[n]
,如果m−
∑i=0
n−1a
i≥0 ,說明這
n 只怪獸可以隨便乾掉,由第
1種情況,乾掉前n−
1 只怪獸每次都有
2 種方案,最後剩乙隻沒別的選擇,故nu
m[n]
=2n−
1,否則nu
m[n]
=0
code
#include
#include
#include
#include
using namespace std;
typedef long
long ll;
namespace fastio
}return *p1++;
}inline bool blank(char ch)
inline void read(int &x)
inline void readlld(ll &x)
#undef buf_size
};using namespace fastio;
#define mod 1000000007
#define maxn 500005
int n,a[maxn],f[maxn],p2[maxn];
ll m;
struct node
};priority_queueque;
int main()
ans+=(ll)sum*f[n-i]%mod;
if(ans>=mod)ans-=mod;
}else
);sum+=p2[max(0,j-1)];
if(sum>=mod)sum-=mod;
}ans+=(ll)sum*f[n-i]%mod;
if(ans>=mod)ans-=mod;
}else }}
if(m>=0)
printf("%d\n",ans);
}return
0;}
HDU 5698 組合數學
傳送門 計算走i步的方法數 走i步 可以分解為在x方向上走的 x1,x2,xi 在y1,y2,yi 步 就是將 n 1分解為i的不為0的數,就相當於在n 2個空裡插入i 1個版 將 m 1 分解為i個不為0的數 也就是 c n 2,i 1 c m 2,i 1 總數也就是sum c n 2,i 1 c...
hdu 6143 組合數學 dp
題意 m個字母,組成兩個長度為n的字元,其中乙個字母不能同時出現在兩個串中。問總方案?思路 列舉m個中恰好有i個在第乙個串,有j個在第二個串。然後求個和。具體其中n個空恰好k種顏色,可以用dp預處理。dp j i dp j 1 i i mod dp j 1 i 1 i mod mod include...
hdu 5106 組合數學 找規律
給定n和r,要求算出 0,r 之間所有n onebit數的和,n onebit數是所有數字中1的個數。對於乙個n bit數,可以根據與r最高不同位的位置分成幾類。比如r 100100010,可以分成0 xx,1000 xx,10010000x三類。x處可任取0或者1。x的個數為n,x中1的個數為k。...