第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛 H-哲哲的疑惑

第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛 H-哲哲的疑惑

链接:https://www.nowcoder.com/acm/contest/90/H

来源:牛客网

题目描述

哲哲有l个球,球是不同的,现在她要用n种颜色给它们染色,如果一种染色方案有k种颜色没有用到,那么哲哲会产生C(k,m)的不满意度。

现在哲哲想求所有方案的不满意度之和,然而她只知道1+1=9,而她的神犇朋友maple去FW战队当中单了不在她身边,所以并不会求,你能帮帮她吗?

输入描述:

三个数n,m,l

1<=n,m<=10^7,l<=10^18

输出描述:

一个数(对998244353取模),表示所有方案的不满意度之和

示例1

输入

3 2 2

输出

3

说明

有以下方案:
两个球同色,有2种颜色没有用到,哲哲产生C(2,2)=1的不满意度,然后这里有三种方案,共产生3的不满意度
两个球不同色,有1种颜色没有用到,哲哲很开心(*^▽^*)
所以总共产生3的不满意度

示例2

输入

1634 1542 130

输出

93812204

说明

无可奉告

思路

答案显然是下式(枚举 i, 表示我用了 i 种颜色):

(为了更好的阅读享受,以下内容使用LaTeX编写,由于第一次使用,折腾了好久)

回顾一下概率论与数理统计的知识:

Ann=n!Crn=(nr)=n!r!(nr)!(25)(26) (25) 全 排 列 公 式 : A n n = n ! (26) 二 项 式 系 数 : C n r = ( n r ) = n ! r ! ( n − r ) !

ans======i=0n(ni)(li)i!f(ni)i=0n(ni)f(ni)j=0i(ij)(1)ijjlj=0njl(1)ji=jn(1)i(ni)(ij)f(ni)j=0njl(1)j(nj)i=jn(1)i(njij)f(ni)j=0njl(nj)i=0nj(1)i(nji)f(nji)j=0njl(nj)i=0nj(1)nji(nji)f(i)(3)(4)(5)(6)(7)(8) (3) a n s = ∑ i = 0 n ( n i ) ∗ ( l i ) ∗ i ! ∗ f ( n − i ) (4) = ∑ i = 0 n ( n i ) ∗ f ( n − i ) ∗ ∑ j = 0 i ( i j ) ∗ ( − 1 ) i − j ∗ j l (5) = ∑ j = 0 n j l ∗ ( − 1 ) j ∗ ∑ i = j n ( − 1 ) i ∗ ( n i ) ∗ ( i j ) ∗ f ( n − i ) (6) = ∑ j = 0 n j l ∗ ( − 1 ) j ∗ ( n j ) ∗ ∑ i = j n ( − 1 ) i ∗ ( n − j i − j ) ∗ f ( n − i ) (7) = ∑ j = 0 n j l ∗ ( n j ) ∗ ∑ i = 0 n − j ( − 1 ) i ∗ ( n − j i ) ∗ f ( n − j − i ) (8) = ∑ j = 0 n j l ∗ ( n j ) ∗ ∑ i = 0 n − j ( − 1 ) n − j − i ∗ ( n − j i ) ∗ f ( i )

f(i)=cm(im)+cm1(im1)++c0(i0)i=0nj(1)nji(nji)f(i)f(i)kf(0)=j=0njl(nj)cnjf(i)=(im)cm=1=nml(nm)(9)(10)(11)(12)(13)(14) (9) 设 : f ( i ) = c m ∗ ( i m ) + c m − 1 ∗ ( i m − 1 ) + … + c 0 ∗ ( i 0 ) (10) ∵ ∑ i = 0 n − j ( − 1 ) n − j − i ∗ ( n − j i ) ∗ f ( i ) 是 把 f ( i ) 差 分 k 次 后 的 f ( 0 ) (11) ∴ 原 式 = ∑ j = 0 n j l ∗ ( n j ) ∗ c n − j (12) ∵ 这 里 f ( i ) = ( i m ) (13) ∴ 只 有 c m = 1 (14) ∴ 原 式 = ( n − m ) l ∗ ( n m )

AC代码

注:使用原始快速幂可以AC。使用优化后的快速幂由于循环会报运行超时,case通过率为90.91%。

#include <iostream>
#include <array>
typedef long long ll;
using namespace std;
const int Mod = 998244353;
const int N = 30000050;
array<int, N> ni;

// 优化后的快速乘
ll QuickMulti_opt(ll a, ll b, ll c) {
    ll ret = 0;
    while(b) {
        if(b&1) {
            ret += a;
            if(ret >= c)
                ret -= c;
        }
        a <<= 1;
        if(a >= c)
            a -= c;
        b >>= 1;
    }
    return ret;
}
// 优化后的快速幂
ll QuickMod_opt(ll a, ll b, ll c) {
    ll ret = 1;
    while(b) {
        if(b&1) {
            ret = QuickMulti_opt(a,ret,c);
        }
        b >>= 1;
        a = QuickMulti_opt(a,a,c);
    }
    return ret;
}

// 原始的快速幂
ll QuickMod(ll a,ll b,ll c) {
    ll ans = 1;
    while(b) {
        if(b&1)
            ans = ans*a%c;
        b >>= 1;
        a = a*a%c;
    }
    return ans;
}

int main() {
    ll n,m,l;
    cin >> n >> m >> l;
    ll ans=1;
    for(int i=n-m+1; i<=n; i++) {
        ans=ans*i%Mod;
    }
    ni[1]=1;
    for(int i=2; i<=m; i++) {
        ni[i]=-1LL*(Mod/i)*ni[Mod%i]%Mod;
    }
    for (int i=1; i<=m; i++) {
        ans=ans*ni[i]%Mod;
    }
    ans=ans*QuickMod_opt(n-m,l,Mod)%Mod;
    cout << (ans+Mod)%Mod << endl;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值