CF891E Lust 生成函式

2022-05-20 07:43:26 字數 1137 閱讀 3727

題意:給你乙個長度為n的序列$a_i$,對這個序列進行k次操作,每次隨機選擇乙個1到n的數x,令$res+=\prod\limits_a_i$(一開始res=0),然後$a_i$--。問最終res的期望值。答案在模意義下對$10^9+7$取模。

$n\le 5000,k\le 10^9$

題解:首先需要發現,假如第i個數被減的次數為$b_i$,則$res=\prod\limits_i a_i-\prod\limits_i (a_i-b_i)$。這個用歸納法容易證明。

於是問題就變成了求$\prod\limits_(a_i-b_i)$

設生成函式$f_i(x)=\sum\limits_$,它等於

$f_i(x)=\sum\limits_j-\sum\limits_j\\=\sum\limits_-x\sum\limits_\\=\sum\limits_j=(a_i-x)e^j$

所以$\prod\limits_i f_i(x)=e^\prod\limits_i (a_i-x)$。我們可以暴力求出$\prod\limits_i (a_i-x)$的每一項係數,設其為$c_i$。剩下的就是求$e^$的第$k-n,k-n+1...k$項係數。顯然第i項係數是$n^i\over i!$,再乘上前面的$$就變成了$\sum\limits_^nn^\prod\limits_^kj$

#include #include #include #include using namespace std;

const int maxn=5010;

typedef long long ll;

const ll p=1000000007;

ll ine[maxn],v[maxn],f[maxn];

int n;

ll k,ans;

int main()

f[0]=f[0]*v[i]%p;

} ine[0]=ine[1]=1;

for(i=2;i<=n;i++) ine[i]=p-(p/i)*ine[p%i]%p;

ll t=1,tmp=1;

for(i=0;i<=n&&i<=k;i++)

printf("%lld",(ans+p)%p);

return 0;

}

CF891E,奇妙的計數題

題面傳送門 題解首先這道題麵裡的 res 其實就是初始n個數的積與k次操作後的期望乘積之差。這個挺顯然的,然而我一開始就沒往這方面去想,反倒想出了什麼倒數和的期望,我好菜啊。知道這個性質後,我想出了乙個o nk2 的dp 然後就是題解裡的演算法,最後居然是o n2 我仔細看了一下,感覺題解這麼優越,...