Sum(快速幂+大整数计算)
Posted leader_win
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sum(快速幂+大整数计算)相关的知识,希望对你有一定的参考价值。
题意:给出一个函数s,该函数值为对于n的s(k)为数列的个数,该数列满足x1,x2……xk为正整数且x1+x2+……+xk=n;求解s(1)+s(2)+……+s(n);
分析:本题最坑的地方在于(1,2)与(2,1)算两种,搞明白这个就可以分析l
对于2来说就是 1
3 : 1,1
4 :1,2,1
5 :1,4,2,1
以此类推可知 其和为2^(n-1);但是n的个数特别大,所以不能直接输入,要采用大数计算方法,一定要用快速幂的方式。
快速幂:a^n=(a^2)^(n/2),这样就可以优化成复杂度O(nlogn)
代码如下:
#include <set> #include <map> #include <stack> #include <queue> #include <math.h> #include <vector> #include <string> #include <utility> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <functional> using namespace std; const int m=1e9+7; long long quick_mod(long long a,long long b) { long long ans=1; while(b){ if(b&1){ ans=(ans*a)%m; b--; } b/=2; a=a*a%m; } return ans; }//内部也用快速幂 long long quickmod(long long a,char *b,int len) { long long ans=1; while(len>0){ if(b[len-1]!='0'){ int s=b[len-1]-'0'; ans=ans*quick_mod(a,s)%m; } a=quick_mod(a,10)%m; len--; } return ans; }//可以以2为基数,但本题要以2为基数嗨哟啊采用大数除法,太麻烦,就以10为基数就好了 int main(){ char s[100050]; while(scanf("%s",s)!=EOF){ for(int i=strlen(s)-1;i>=0;i--){ if(s[i]!='0'){ s[i]-=1; break; } else { s[i]='9'; } }//减一,模拟整数减法 int len=strlen(s); if(s[0]=='0'){ for(int i=0;i<len;i++) s[i]=s[i+1]; len--; } //判断第一个数是不是0 printf("%I64d\n",quickmod(2,s,len)); } return 0; }
以上是关于Sum(快速幂+大整数计算)的主要内容,如果未能解决你的问题,请参考以下文章
hdu 4704 Sum (整数和分解+快速幂+费马小定理降幂)
模幂运算问题,使用朴素算法和重复-平方算法(快速幂+C#计算程序运行时间)