codeforces #451E Devu and Flowers 不定方程解的个数+lucas定理

题意:链接

方法:不定方程解的个数+lucas定理

解析:

感觉做了这么多不定方程解的个数之后,每一次就是改一次组合数求法- -!

这次mod的是质数,并且观察到n,m可能大于mod,所以lucas裸上..

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 25
#define mod 1000000007
using namespace std;
typedef long long ll;
int n;
ll s;
ll f[N];
ll quick_my(ll x,ll y,ll Mod)
{
    ll ret=1;
    while(y)
    {
        if(y&1)ret=(ret*x)%Mod;
        x=(x*x)%Mod;
        y>>=1;
    }
    return ret;
}
ll get_c(ll n,ll m)
{
    if(n<m)return 0;
    if(m>n-m)m=n-m;
    ll top=1,bot=1;
    for(int i=1;i<=m;i++)
    {
        top=(top*(n-i+1))%mod;
        bot=(bot*i)%mod;
    }
    return top*quick_my(bot,mod-2,mod)%mod;
}
ll Lucas(ll n,ll m)
{
    if(m==0)return 1;
    return get_c(n%mod,m%mod)*Lucas(n/mod,m/mod)%mod;
}
ll ans;
void dfs(int now,int cnt,ll sum)
{
    if(now==n+1)
    {
        if(s-sum<0)return;
        if(cnt&1)ans=((ans-Lucas(s-sum+n-1,n-1))%mod+mod)%mod;
        else ans=(ans+Lucas(s-sum+n-1,n-1))%mod;
        return;
    }
    dfs(now+1,cnt,sum);
    dfs(now+1,cnt+1,sum+f[now]+1);
}
int main()
{
    scanf("%d%lld",&n,&s);
    for(int i=1;i<=n;i++)scanf("%lld",&f[i]);
    dfs(1,0,0);
    printf("%lld\n",ans);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-01 14:54:00

codeforces #451E Devu and Flowers 不定方程解的个数+lucas定理的相关文章

codeforces 451E Devu and Flowers

题意:有n个瓶子每个瓶子有 f[i] 支相同的颜色的花(不同瓶子颜色不同,相同瓶子花视为相同) 问要取出s支花有多少种不同方案. 思路: 如果每个瓶子的花有无穷多.那么这个问题可以转化为  s支花分到n个瓶子有多少种方案  用隔板法就能解决 C(s+n-1,n-1) .有限制之后我们可以 用 没限制的去减掉那些违反限制的 如果只有一个瓶子取得花超出上限 那么减去,两个瓶子 要加上(容斥原理) n只有20  就能暴力枚举那些取超过上限f[i]的瓶子并且在这些瓶子至少选出 f[i]+1 支花  统计

Codeforces 451E Devu and Flowers(容斥原理)

题目链接:Codeforces 451E Devu and Flowers 题目大意:有n个花坛.要选s支花,每一个花坛有f[i]支花.同一个花坛的花颜色同样,不同花坛的花颜色不同,问说能够有多少种组合. 解题思路:2n的状态,枚举说那些花坛的花取超过了,剩下的用C(n?1sum+n?1)隔板法计算个数.注意奇数的位置要用减的.偶数的位置用加的.容斥原理. #include <cstdio> #include <cstring> #include <cmath> #in

Codeforces 451E Devu and Flowers(组合计数)

题目地址 在WFU(不是大学简称)第二次比赛中做到了这道题.高中阶段参加过数竞的同学手算这样的题简直不能更轻松,只是套一个容斥原理公式就可以.而其实这个过程放到编程语言中来实现也没有那么的复杂,不过为了让计算机在限定的时间内完成计算需要进行一些对计算上的优化.模MOD的情况下计算组合数nCr只需要求出分子再乘以分母的逆元,考虑到模的是1e9+7本身就是一个质数,根据费马小定理a^(MOD-2)即是a在模MOD意义下的逆元.求逆元的时候为了节约计算时间可以采用快速幂.计算过程就是容斥原理,就没有什

BZOJ 3129 [Sdoi2013]方程 不定方程解的个数+组合数取模

题意:链接 方法:不定方程解的个数+组合数取模 解析: 先看n1与n2的部分的限制. 对于后半部分的限制来说,我们直接减去An1+i?1就可以转化一下求正整数解. 但是前半部分呢? 跟上一道猴子那个很像. 所以我们容斥搞就行了. 但是这道题好像不好写的地方不在这? 这题TMD不就是礼物吗! 大组合数取模如何取? 请参见我<BZOJ 礼物>的题解. 另外吐槽题干 明明是X1+X2+-+Xn=m 并不是小于等于 代码: #include <cstdio> #include <cs

Codeforces #258 Div.2 E Devu and Flowers

大致题意: 从n个盒子里面取出s多花,每个盒子里面的花都相同,并且每个盒子里面花的多数为f[i],求取法总数. 解题思路: 我们知道如果n个盒子里面花的数量无限,那么取法总数为:C(s+n-1, n-1) = C(s+n-1, s). 可以将问题抽象成:x1+x2+...+xn = s, 其中0<=xi <= f[i],求满足条件的解的个数. 两种方法可以解决这个问题: 方法一:这个问题的解可以等价于:mul = (1+x+x^2+...+x^f[1])*(1+x+x^2+...+x^f[2]

Codeforces Round #258 (Div. 2)Devu and Flowers 容斥原理

题目:Codeforces Round #258 (Div. 2)Devu and Flowers 题意:n个boxes ,第i个box有fi个flowers,每个boxes中的flowers完全相同,不同boxes的flowers不同,求从n个boxes中取出s个flowers的方案数.n<=20,s<=1e14,fi<=1e12. 排列组合的题目,一解法可用容斥原理(inclusion exclusion principle) . 有2中写法dfs和集合.下为集合写法. #inclu

Codeforces 451 E. Devu and Flowers(组合数学,数论,容斥原理)

传送门 解题思路: 假如只有 s 束花束并且不考虑 f ,那么根据隔板法的可重复的情况时,这里的答案就是 假如说只有一个 f 受到限制,其不合法时一定是取了超过 f 的花束 那么根据组合数,我们仍然可以算出其不合法的解共有: 最后,由于根据容斥,减两遍的东西要加回来,那么含有偶数个 f 的项为正,奇数个时为负. 答案就是: 搜索答案,使用Lucas定理,计算组合数上下约去. 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include&

codeforces 439D Devu and Partitioning of the Array(有深度的模拟)

题目 //参考了网上的代码 注意答案可能超过32位 //要达成目标,就是要所有数列a的都比数列b的要小或者等于 //然后,要使最小的要和最大的一样大,就要移动(大-小)步, //要使较小的要和较大的一样大,也是要移动(较大-较小)步 //然后都加在一起就好了 #include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> using namespace std; #def

Codeforces 439E Devu and Birthday Celebration(计数问题)

题目链接:Codeforces 439E Devu and Birthday Celebration 题目大意:给出q,表示询问的次数,每次询问有n和f,问有多少种分类方法,将n分成f份,并且这f份的最大共约数为1. 解题思路:如果不考虑说最大共约数为1的话,那么问题很简单,就是f个数的和为n的种数C(f?1n?1).所以我们就尽量将问题转化成说f数的和为s的子问题.用容斥原理,总的可能减去公约数不为1的情况,那么公约数不为1的情况就去枚举公约数. #include <cstdio> #inc