[2018 ACM-ICPC 焦作赛区网络赛] G - Give Candies(找规律+快速幂)
Posted jiaqi666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[2018 ACM-ICPC 焦作赛区网络赛] G - Give Candies(找规律+快速幂)相关的知识,希望对你有一定的参考价值。
There are N children in kindergarten. Miss Li bought them N candies. To make the process more interesting, Miss Li comes up with the rule: All the children line up according to their student number (1...N)(1...N), and each time a child is invited, Miss Li randomly gives him some candies (at least one). The process goes on until there is no candy. Miss Li wants to know how many possible different distribution results are there.
Input
The first line contains an integer T, the number of test case.
The next T lines, each contains an integer N.
1≤T≤100
1≤N≤10^100000
Output
For each test case output the number of possible results (mod 1000000007).
样例输入
1 4
样例输出
8
题意:有一位老师给N个学生分N个糖果,老师从第一个学生开始发糖果,老师所经过的学生至少要被分到一个糖果,求有多少种分法,比如这里有三个学生,老师有三个糖果,有四种分法:{3,0,0},
{2,1,0},{1,2,0},{1,1,1}。
思路:这个题和HDU - 5703类似,其实就是拆数问题,一个数的拆法其实就是2^(N-1),具体证明过程可以直接搜刚才杭电那道题的题解,所以这道题其实就是让你算2^(N-1),但是题目给的N特别大,
可以达到10^100000,我们只能用字符串读这个数,这样的话我们肯定不能直接用快速幂算,其实有一个性质,2^N模一个质数,它的结果是具有周期性的,周期长度为mod-1,这道题就利用这个周期
性,具体步骤就是:先把N转化成模mod-1下的的数,然后用这个数计算快速幂,得到的结果是和原数相同的。
#include <iostream> using namespace std; #define ll long long int mod = 1000000007; ll qmul(ll x, ll y, ll mod) // 乘法防止溢出, 如果p * p不爆LL的话可以直接乘; O(1)乘法或者转化成二进制加法(快速加) { ll ret = 0; while(y) { if(y & 1) ret = (ret + x) % mod; x = x * 2 % mod; y >>= 1; } return ret; } ll qpow(ll a, ll n, ll mod) { ll ret = 1; while(n) { if(n & 1) ret = qmul(ret, a, mod); a = qmul(a, a, mod); n >>= 1; } return ret; } int main(){ int T; cin>>T; while(T--){ string s; cin>>s; mod-=1; long long ans = 1,tmp = 0; for(int i=0;i<s.length();i++){ tmp = (tmp * 10 + s[i] - ‘0‘)%mod; } if(tmp==0) //注意0要特判 tmp=mod; tmp = (tmp-1+mod)%(mod); mod+=1; ans = qpow(2,tmp,mod); cout<<ans<<endl; } }
以上是关于[2018 ACM-ICPC 焦作赛区网络赛] G - Give Candies(找规律+快速幂)的主要内容,如果未能解决你的问题,请参考以下文章
ACM-ICPC 2018 焦作赛区网络预赛 G题 Give Candies
ACM-ICPC 2018 焦作赛区网络预赛G Give Candies(欧拉降幂)