矩阵妙用-求解高度为h的AVL树的最少节点数

初次编辑时间:2010-03-25

AVL树
Time Limit:1000MS  Memory Limit:65536K
Total Submit:39 Accepted:15

Description
AVL树是一种平衡树,它的左右子树的高度差不能超过1。一棵高度为h的AVL树的最少节点数的递推公式为S(h)=S(h-1)+S(h-2)+1,已经知道S(1)=1,S(2)=2,现在问题是给定一个h (1<=h<=1000000000),求S(h)%m,2<=m<=1000000000。

Input
输入两个数h,m,其含意如上面所述。

Output
输出S(h)%m

Sample Input
1  100
2  100
3  100

Sample Output
1
2
4

//矩阵法求解
#include<stdio.h>
#include<string.h>
main()
{
    int N,M,i,j,k,t,a,b,A[3][3],B[3][3],C[3][3];
    const int K=3;
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        if(N==1)
            t=1;
        else if(N==2)
            t=2;
        else
        {
            N-=3;
            memset(B,0,sizeof(B));
            for(i=0;i<K;i++)
                B[0][i]=1;
            B[1][0]=1;B[2][2]=1;
            memcpy(A,B,sizeof(B));
            while(N)
            {
                if(N%2)
                {
                    for(i=0;i<K;i++)
                        for(j=0;j<K;j++)
                        {
                            for(t=0,k=0;k<K;k++)
                            {
                                a=A[i][k];b=B[k][j]; //计算a*b  考虑到精度要求用加法计算,为保证时间效率,用二分求幂法计算、
                                while(b)
                                {
                                    if(b%2) t=(t+a)%M;
                                    a=(a+a)%M;
                                    b/=2;
                                }
                            }
                            t%=M;
                            C[i][j]=t;
                        }
                    memcpy(B,C,sizeof(C));
                }
                for(i=0;i<K;i++)
                    for(j=0;j<K;j++)
                    {
                        for(t=0,k=0;k<K;k++)
                        {
                            a=A[i][k];b=A[k][j];  //计算a*b  考虑到精度要求用加法计算,为保证时间效率,用二分求幂法计算、
                            while(b)
                            {
                                if(b%2) t=(t+a)%M;
                                a=(a+a)%M;
                                b/=2;
                            }
                        }
                        t%=M;
                        C[i][j]=t;
                    }
                memcpy(A,C,sizeof(C));
                N/=2;
            }
            t=B[0][0]*2%M;
            t=(t+B[0][1])%M;
            t=(t+B[0][2])%M;
        }
        printf("%d\n",t);
    }
}

    原文作者:AVL树
    原文地址: https://blog.csdn.net/jinghuaboy/article/details/45337637
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞