牛客网暑期ACM多校训练营(第六场) C

题意
你对n个集合进行n次操作,第i次操作都从第i个集合开始,每次操作可以向从i到n的集合中插入一个元素,元素范围为,n个集合为一个大集合,问你有多少个不同的大集合
思路
我们以n=4,m=4为例,先举一个4,4的两个集合


我们现在只看第n层,两个不同的集合的最后一层的元素都含有1,2,3,但是这两个集合是不同的两个集合,原因是数字出现的顺序会影响上一层的集合,所以最后一层元素的顺序是影响总的个数的,那么我们假设第n层由k个元素,方案数就是相当于从m个数中选k个数的排列数,即,选定好这k个数后,答案还不是,因为由于他可以插重复的元素,而重复的元素只与其他第一次出现有关,例如


这里是两个不同的集合,而不同的原因是来自于,2出现的位置,由于第一个元素是固定的如
1,1,1,2,1,2{1,2},1,1,2,1,1,2{1,2},第一个出现的数会把第二个出现的数的前面都填满,而第二个出现的数才对答案有贡献,所以就相当于在n-1个位置上填k-1个数即,那么答案就应该是,如何k从1枚举到min(n,m),即

n和m都比较大,但两者肯定有一个较小,所以最多只用算1e6个数组合和排列数最多也只有算,所以多处理一个1到1e6的逆元就可以了
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;
const long long mod=998244353;
const int N=1e6+5;
long long inv[N];
int main()
{
    inv[0]=inv[1]=1;
    for(int i=2; i<N; ++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    int t,cas=1;
    scanf("%d",&t);
    while(t--)
    {
        long long n,m;
        scanf("%lld%lld",&n,&m);
        long long ans=m%mod,sum=m%mod;
        long long m_=m%mod,n_=n%mod;
        for(int i=1; i<min(n,m); i++)
        {
            sum=sum*(m_-i)%mod*(n_-i)%mod*inv[i]%mod;
            ans=(ans+sum)%mod;
        }
        printf("Case #%d: %lld\n",cas++,(ans+mod)%mod);
    }
    return 0;
}

全部评论

相关推荐

牛马为难牛马中,疑似阿里的员工看某个从拼多多跳槽过来的员工抢他的A+绩效不顺眼,反手向多多举报的,结果导致人家竞业被发现了,违约金5w,赔偿100+w上海长宁区劳动人事争议仲裁委公告显示:上海寻梦信息技术有限公司(拼多多主体)与一名员工的劳动争议案,因被申请人未到庭,仲裁委依法缺席裁决。结果是,该员工需要返还已发放的竞业补偿58,211.29元,并按约支付违约金1,089,103元。公告自发布30日后视为送达,15日内不诉即生效
nova!1028:竞业避坑指南:1、平时戴口罩及帽子、墨镜,不在公共场所露面 2、不在现有公司收快递 3、自己竞业期间社保缴纳不挂靠,最好不交 4、三方公司不能对外说可挂医社保 5、记住社保缴纳地的地址 6、注意陌生可疑电话,比如猎头 7、自己名下车子不要出入到服务的场所 8、竞业到期后不能马上出现在竞对公司股东信息上 9、注意平台简历内容,会被取证 10、竞业期过后,不要透露过往,以防被追溯 11、非必要不开大会和培训,注意公司内鬼 12、不在社交平台展示自己 13、电话卡不用自己名字登记 14、注意陌生的外卖 15、注意动车票信息 16、竞业期低调不结仇 复制过来的
点赞 评论 收藏
分享
评论
8
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务