HDU 4704 Sum

来源:互联网 发布:淘宝考试不 编辑:程序博客网 时间:2024/06/16 02:15

题意为: 将n(小于等于10的十万次方),分别拆成1个数,2个数...n个数的方案和。

由插板法我们可以知道,每一个问题可以看做有n个球,需要插入(i-1)个板的答案。即从n-1个空里面找i-1个位置来

插板的方案数,即C(i-1,n-1),由组合数的求和我们便可以知道,这个问题的答案就是求和C(0~n-1,n-1),答案

即为2的n-1次方。数据过大,我们可以使用费马小定理进行降幂,或者使用十进制快速幂来完成。

下附AC代码。

#include<iostream>#include<string.h>#define maxn 100005using namespace std;const long long  MOD=1e9+7;long long quickmul(long long n,long long k){long long ans=0;while(k){if(k&1){ans=(ans+n)%MOD;}n=(n+n)%MOD;k=k>>1;}return ans;}long long quickpow(long long n,long long k){long long ans=1;while(k){if(k&1){ans=quickmul(ans,n);}n=quickmul(n,n);k=k>>1;}return ans;}long long quickpowbaseon10(long long n,string s){long long ans=1;long long powVal[10];powVal[0]=1;for(int i=1;i<=9;i++){powVal[i]=quickmul(powVal[i-1],n);}for(int i=0,t=s.size();i<t;i++){ans=quickmul(ans,powVal[s[i]-'0']);if(i!=t-1){ans=quickpow(ans,10);}}return ans%MOD;}int a[maxn],b[maxn],c[maxn];int main(){string s;string j="1";while(cin>>s){memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c));int lena=s.size(),lenb=j.size();for (int i=0;i<=lena-1;i++) a[lena-i]=s[i]-'0';    for (int i=0;i<=lenb-1;i++) b[lenb-i]=j[i]-'0';int now=1;    while (now<=lena)    {        if (a[now]<b[now])        {            a[now]+=10;            a[now+1]--;        }        c[now]=a[now]-b[now];        now++;    }    for (int i=now;i>=1;i--)    if ((c[i]==0)&&(now>1)) now--;else break;  string ans="";      for (int i=now;i>=1;i--)    {    ans+=(c[i]+'0');}cout<<quickpowbaseon10(2,ans)<<endl;}}

原创粉丝点击