CF891E Lust

link

\(b_i\)\(a_i\) 被搞了多少次
\(P=\prod a_i\),对于一次操作,\(P\) 会减小 \(\prod\limits_{i\neq j} a_j\) ,也就是操作的代价
所以全部操作下来的代价就是 \(\prod a_i-\prod (a_i-b_i)\)
问题就是求后面的期望
考虑一个位置的 EGF

\[\hat {F_i}=\sum_{j=0}^\infty \frac{(a_i-j)x^j}{j!}=(a_i-x)e^x \]

全乘起来就是 \(A(x)e^{nx}\)
期望就是

\[E=\frac{k!}{n^k}\sum_{i=0}^n A_i\frac{n^{k-i}}{(k-i)!}=\sum_{i=0}^n A_i\frac{k^{\underline i}}{n^i} \]

\(n\) 比较小可以暴力多项式乘法,复杂度 \(O(n^2)\),不难利用分治 FFT 做到 \(O(n\log^2n)\)

#include <bits/stdc++.h>

using namespace std;

# define Rep(i,a,b) for(int i=a;i<=b;i++)
# define _Rep(i,a,b) for(int i=a;i>=b;i--)
# define RepG(i,u) for(int i=head[u];~i;i=e[i].next)

const int N=5005;
const int mod=1e9+7;

typedef long long ll;
typedef double db;

# define chkmax(a,b) a=max(a,b)
# define chkmin(a,b) a=min(a,b)
# define PII pair<int,int>
# define mkp make_pair

template<typename T> void read(T &x){
    x=0;int f=1;
    char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-'0';
    x*=f;
}

int n,k;
int a[N];
int poww[N],dpow[N];
int A[N];
int ans=1;

int inc(int x,int y){
    return x+y>=mod?x+y-mod:x+y;
}

int dec(int x,int y){
    return x<y?x-y+mod:x-y;
}

int Qpow(int base,int ind){
    int res=1;
    while(ind){
        if(ind&1)res=1ll*res*base%mod;
        base=1ll*base*base%mod;
        ind>>=1;
    }
    return res;
}   

int main()
{
    # ifndef ONLINE_JUDGE
    freopen("testdata.in","r",stdin);
    //freopen("test1.out","w",stdout);
    # endif
    read(n),read(k);
    Rep(i,1,n)read(a[i]),ans=1ll*ans*a[i]%mod;
    int in=Qpow(n,mod-2);
    poww[0]=dpow[0]=1;
    Rep(i,1,n)poww[i]=1ll*poww[i-1]*in%mod;
    Rep(i,1,n)dpow[i]=1ll*dpow[i-1]*(k-i+1+mod)%mod;
    A[0]=1;
    Rep(i,1,n){
        _Rep(j,i,1)
            A[j]=dec(1ll*A[j]*a[i]%mod,A[j-1]);
        A[0]=1ll*A[0]*a[i]%mod;
    }
    Rep(i,0,n)ans=dec(ans,1ll*A[i]*dpow[i]%mod*poww[i]%mod);
    printf("%d\n",ans);
    return 0;
}
posted @ 2022-05-20 16:07  YuukiYumesaki  阅读(25)  评论(0编辑  收藏  举报