ICPC 2018 焦作赛区网络预赛G Give Candies 组合数学隔板法+欧拉降幂

G Give Candies

计蒜客 G Give Candies

题意

n n n个糖果, n n n个人从 1 ∼ n 1\sim n 1n编号,每次给一个人发糖可以发任意数量但不能小于 1 1 1,直到发完所有糖果,问分糖果的方案有多少种。

分析

1.首先考虑到会不会有一个人被重复发糖,但最后发现对答案没有影响,因为对同一个人发两次糖每次发一颗 和 一次发两颗对于最后的糖果分配结果来看没有区别。

2.考虑会不会有编号的影响,只要对于任意两个方案,只要有编号相同的人持有不同数量的糖果就视为不同方案,也就是说 n = 4 n = 4 n=4,给一个人发 4 4 4个糖果的方案有四种 即给 1 , 2 , 3 , 4 1,2,3,4 1,2,3,4的某一个发 4 4 4个糖果其他人不发。但样例 n = 4 n = 4 n=4 a n s = 8 ans = 8 ans=8可以分析出来,编号对方案不造成影响,最后的答案按糖果数量排序后,字典序不同才是不同方案 0 , 0 , 0 , 4 = 0 , 4 , 0 , 0 0,0,0,4 = 0,4,0,0 0,0,0,4=0,4,0,0

3. 此时可以将问题抽象出来: n n n个糖果将其分成 1 , 2 , … … , n 1,2,……,n 1,2,……,n份的方案数之和,我们采用隔板法。n个糖果共有 n − 1 n - 1 n1个地方可以插入隔板,插入 0 0 0个隔板是分成 1 1 1 C n − 1 0 C_{n - 1}^{0} Cn10,插入 1 1 1个隔板是分成 2 2 2 C n − 1 1 C_{n - 1}^{1} Cn11,……
a n s = ∑ i = 0 n − 1 C n − 1 i = 2 n − 1 ans = \sum_{i = 0}^{n - 1} C_{n - 1}^{i} = 2^{n - 1} ans=i=0n1Cn1i=2n1

4.但是 n n n的数据较大 n < = 1 0 100000 n <= 10^{100000} n<=10100000 普通的递推和快速幂都无法满足于是我们需要使用欧拉降幂,将指数的幂降下去,再用快速幂求解。
欧拉降幂结论: ( a b ) m o d    p = ( a b m o d    ( p − 1 ) ) m o d    p (a ^ b) \mod p = (a ^ {b \mod (p - 1)}) \mod p (ab)modp=(abmod(p1))modp 当且仅当 a a a p p p互质。

代码

#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
const int N = 100010;
const int p = 1000000006;//mod - 1
const int mod = 1000000007;//mod
char num[N];
ll ksm(ll a,ll b)
{
    ll ans = 1;
    while(b)
    {
        if(b & 1) ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}
void solve()
{
    scanf("%s",num);
    int len = strlen(num);
    ll mi = 0;
    for(int i = 0; i < len; i ++)
    {
        mi = mi * 10 % p;
        mi = (mi + num[i] - '0') % p;//降幂
    }
    mi = (mi + p - 1) % p;
    printf("%lld\n",ksm(2, mi));
    return ;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)solve();
    return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值