[HAOI2018]染色(NTT)

前置芝士

可重集排列
NTT

前置定义

\[\begin{aligned}\\ f_i=C_m^i\cdot \frac{n!}{(S!)^i(n-iS)!}\cdot (m-i)^{n-iS}\\ ans_i=\sum\limits_{j=i}^lim (-1)^{j-i}C_j^i f_j\\ \end{aligned}\]

理解:\(m\)种颜色选i种恰好出现\(S\)次,可重全排列,剩余块染色,不过这样有可能会出现剩余块种有恰好出现\(S\)次的情况,所以容斥一下

\(C_j^i\)\(f_j\)里一定包含着\(f_i\),要减掉,同时有可能减掉了在原本\(j+1..\)的东西

推式

\[\begin{aligned}\\ ans_i=\sum\limits_{j=i}^{lim} (-1)^{j-i}\frac{j!}{i!(j-i)!}f_j\\ ans_i\cdot i!=\sum\limits_{j=i}^{lim}(\frac{(-1)^{j-i}}{(j-i)!})\cdot (f_j\cdot j!)\\ \end{aligned}\]

设生产函数\(G,F\)分别对应\((\frac{(-1)^{j-i}}{(j-i)!}),(f_j\cdot j!)\),再把\(F\)翻转一下:
\[\begin{aligned}\\ ans_i\cdot i!&=\sum\limits_{j=i}^{lim}G_{j-i}\cdot F_{lim-j}\\ H&=G*F\\ ans_i\cdot i!&=H_{lim-i}\\ \end{aligned}\]

Code

\(NTT\)模板就行

#include<bits/stdc++.h>
typedef long long LL;
const LL mod=1004535809,gg=3,maxn=1e7+9;
inline LL Read(){
    LL x(0),f(1); char c=getchar();
    while(c<'0' || c>'9'){
        if(c=='-') f=-1; c=getchar();
    }
    while(c>='0' && c<='9'){
        x=(x<<3)+(x<<1)+c-'0'; c=getchar();
    }
    return x*f;
}
inline LL Pow(LL base,LL b){
    LL ret(1);
    while(b){
        if(b&1) ret=ret*base%mod; base=base*base%mod; b>>=1;
    }return ret;
}
LL fac[maxn],fav[maxn],r[maxn];
inline LL Get_c(int n,int m){
    return fac[n]*fav[m]%mod*fav[n-m]%mod;
}
inline LL Fir(LL n){
    LL limit(1),len(0);
    while(limit<(n<<1)){
        limit<<=1; ++len;
    }
    for(int i=0;i<limit;++i) r[i]=(r[i>>1]>>1)|((i&1)<<len-1);
    return limit;
}
inline void NTT(LL *a,int n,int type){
    for(int i=0;i<n;++i) if(i<r[i]) std::swap(a[i],a[r[i]]);
    for(LL mid=1;mid<n;mid<<=1){
        LL wn(Pow(gg,(mod-1)/(mid<<1)));
        if(type==-1) wn=Pow(wn,mod-2);
        for(LL R=mid<<1,j=0;j<n;j+=R){
            for(LL k=0,w=1;k<mid;++k,w=w*wn%mod){
                LL x(a[j+k]),y(a[j+mid+k]*w%mod);
                a[j+k]=(x+y)%mod; a[j+mid+k]=(x-y+mod)%mod;
            }
        }
    }
    if(type==-1){
        LL ty(Pow(n,mod-2));
        for(int i=0;i<n;++i) a[i]=a[i]*ty%mod;
    }
}
LL n,m,S,lim,ret;
LL W[maxn],f[maxn],g[maxn],h[maxn],ans[maxn];
int main(){
    n=Read(); m=Read(); S=Read();
    for(int i=0;i<=m;++i) W[i]=Read();
    lim=std::min(m,n/S);
    fac[0]=fac[1]=1;
    int up(std::max(n,m));
    for(int i=2;i<=up;++i) 
        fac[i]=fac[i-1]*i%mod;
    fav[up]=Pow(fac[up],mod-2);
    for(int i=up;i>=1;--i) 
        fav[i-1]=fav[i]*i%mod;
    for(int i=0;i<=lim;++i)
        f[i]=Get_c(m,i)*fac[n]%mod* Pow(Pow(fac[S],i),mod-2)%mod *fav[n-i*S]%mod *Pow(m-i,n-i*S)%mod *fac[i]%mod;
    for(int i=0;i<=(lim>>1);++i) 
        std::swap(f[i],f[lim-i]);
    for(int i=0;i<=lim;++i)
        g[i]=(Pow(-1,i)*fav[i]+mod)%mod;
    LL limit(Fir(lim+1));
    NTT(f,limit,1); NTT(g,limit,1);
    for(int i=0;i<limit;++i) h[i]=g[i]*f[i]%mod;
    NTT(h,limit,-1);
    
    for(int i=0;i<=lim;++i) ans[i]=h[lim-i]*fav[i]%mod;
    for(int i=0;i<=lim;++i) ret=(ret+ans[i]*W[i]%mod)%mod;  
    printf("%lld\n",ret);
    return 0;
}

转载于:https://www.cnblogs.com/y2823774827y/p/10699933.html

基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值