zoukankan      html  css  js  c++  java
  • 数据结构与算法分析

    (1).秦九韶算法:

    把一个N次的多项式,改写成如下形式:
    [egin{array}{l}
    f( x ) = a_n{x^n} + a_{n - 1}x^{n - 1} +  cdots  + {a_1}x + a_0\
    = ( {a_n}x^{n - 1} + a_{n - 1}x^{n - 2} +  cdots  + {a_1} )x + a_0\
    = ( ( ( {a_n}x + a_{n - 1} )x + a_{n - 2}) +  cdots  + a_1)x + a_0
    end{array}]

    令:
    [egin{array}{*{20}{l}}
    {{b_1} = {a_n}x + {a_{n - 1}}}\
    {{b_2} = {b_1}x + {a_{n - { m{2}}}}}\
    { cdots  cdots }\
    {{b_n} = {b_{n - 1}}x + {a_{ m{1}}}}
    end{array}]

    则:

    [f(x) = {a_n}{x^n} + cdots + a_0 = b_n]

    这样做的好处就是:通过递归求解数列 {bn} 我们最终获得多项式的值,减少了幂运算和防止INT范围溢出。

    (2).快速幂算法
    求解:${a^b}mod c = ?$

    令:
    [b_{( 10 )} = overline {a_n}a_{n - 1} cdots a_1{a_0} _{( 2 )} = a_n{2^n} + a_{n - 1}2^{n - 1} +  cdots  + a_1{2^1} + a_0]

    故:
    [a^b = a^{a_n{2^n}}a^{a_{n - 1}2^{n - 1}} cdots  a^{a_1{2^1}} a^{a_0}]


    [{a^b}mod c = [ {( {{a^{{a_n}{2^n}}}mod c} )( {{a^{{a_{n - 1}}{2^{n - 1}}}}mod c} ) cdots ( {{a^{{a_1}{2^1}}}mod c} )( {{a^{{a_0}}}mod c} )} mod c,{a_i} = { {0,1|i in [ {1,n} ]} }]

    实际上,我们还可以用移位方式表示 ai :
    [a_i = b >  > i & 1,i in [ 1,n ]]

    (3).代码模板:

    1: //整数的快速幂 m^n % k 的快速幂:
    2: long long quickpow(long long m , long long n , long long k){
    3: long long ans = 1;
    4: while(n){
    5: if(n&1)//如果n是奇数
    6: ans = (ans * m) % k;
    7: n = n >> 1;//位运算“右移1类似除1”
    8: m = (m * m) % k;
    9: }
    10: return ans;
    11: }

    (4).代码解释:

    这里的a为底数,需要区别于ai
    [egin{array}{l}
    if( a_i == 1),a^{a_i{2^i}} = a^{2^i}\
    if (a_i == 0),a^{a_i{2^i}} = 1
    end{array}]

    在这里我们记:(i代表第i位)
    [p_k = a^k,k = 2^i]

    则我们可以获得数列 { pk },递推式为:
    [p_k = ( {p_{k - 1}^2} )mod c, p_0 = amod c]

    (5).样例实验

    hdu 2035 - 人见人爱A^B

    题意:求解(A^B)%1000

    解法:自然是快速幂。

    附上我的代码:

    1: #include<cstdio>
    2: #include<cstdlib>
    3: using namespace std;
    4: //计算(a^p)%m
    5: long long int fast_pow(long long a,long long p,long long m){
    6: long long ans=1;
    7: while(p){
    8: if(p&1) ans=(ans*a)%m;
    9: p=p>>1;
    10: a=(a*a)%m;
    11: }
    12: return ans;
    13: }
    14: int main(){
    15: int n,m;
    16: while(scanf("%d %d",&n,&m)!=EOF && (n||m)){
    17: printf("%d ",fast_pow(n,m,1000));
    18: }
    19: }
  • 相关阅读:
    ACM训练计划
    动态规划 最长公共子序列LCS
    Floyd最短路
    邻接表拓扑排序
    数字三角形(数塔) DP入门
    hdu 5533 计算几何 判断是否为正方形
    威尔逊定理--HDU2973
    二分--POJ-3258
    01背包--hdu2639
    矩阵快速幂--51nod-1242斐波那契数列的第N项
  • 原文地址:https://www.cnblogs.com/ZJUT-jiangnan/p/3656279.html
Copyright © 2011-2022 走看看