HDU 6030(构造矩阵)

来源:互联网 发布:网络打黄油是什么意思 编辑:程序博客网 时间:2024/05/28 23:10

Little Q wants to buy a necklace for his girlfriend. Necklaces are single strings composed of multiple red and blue beads.
Little Q desperately wants to impress his girlfriend, he knows that she will like the necklace only if for every prime length continuous subsequence in the necklace, the number of red beads is not less than the number of blue beads.
Now Little Q wants to buy a necklace with exactly n beads. He wants to know the number of different necklaces that can make his girlfriend happy. Please write a program to help Little Q. Since the answer may be very large, please print the answer modulo109+7.
Note: The necklace is a single string, {not a circle}.
 

Input
The first line of the input contains an integer T(1T10000), denoting the number of test cases.
For each test case, there is a single line containing an integer n(2n1018), denoting the number of beads on the necklace.
 

Output
For each test case, print a single line containing a single integer, denoting the answer modulo109+7.
 

Sample Input
223
 

Sample Output
34
题意:
有红蓝两种颜色的珠子,要组成一个长串(不成环),对任意连续质数个串需满足红珠子数不大于蓝珠子数,给你串的长度,让你统计有多少种情况。
思路:
先分析数据范围:n达到了10的18次方,肯定long long,而且对1e9+7取余,肯定不能用递归来做,也不会是DP,而目前接触到的涉及到的有关于幂运算的也只有快速幂和快速矩阵了,那就先列出来前几项找找规律吧。
先说说心酸的血泪史:
比赛的时候列的是:
2-3
3-4
4-8
5-12
6-21
发现是个类似于斐波那契的东西,因为偶数项是前两项之和加1,这个应该是可以用构造矩阵来做的,但是......转移矩阵没有构造出来......所以这题就无解了
比赛完了问了问别人咋做的,也是说构造矩阵,详细问了问才发现是关系找错了,因为列表就列错了.......尴尬......
正确的解法:
2-3
3-4
4-6
5-9
6-13
7-19
8-28
发现第n项是n-1项+n-3项
这样就可以构造矩阵了
an              1  0  1        an-1
an-1=        1  0  0 *      an-2
an-2          0  1  0       an-3
中间那个就是转移矩阵
因为初始值是a4,a3,a2,当幂值是1是,得n=5,所以要得an,就要带入幂值为n-4
之后注意答案an是转移矩阵第一行乘初始值,每一项都要乘

#include <iostream>#include <string.h>#include <stdio.h>using namespace std;typedef long long LL;const int N = 3;const int MOD = 1000000007;struct Matrix{    LL m[N][N];};Matrix I = {//I主对角线是1       1,0,0,       0,1,0,       0,0,1};Matrix multi(Matrix a,Matrix b)//矩阵乘法{    Matrix c;    for(int i=0;i<N;i++)    {        for(int j=0;j<N;j++)        {            c.m[i][j] = 0;            for(int k=0;k<N;k++)                c.m[i][j] += a.m[i][k] * b.m[k][j] % MOD;            c.m[i][j] %= MOD;        }    }    return c;}Matrix power(Matrix A,LL k)//矩阵A的k次幂(快速幂){    Matrix ans = I,p = A;    while(k)    {        if(k&1)        {            ans = multi(ans,p);            k--;        }        k >>= 1;        p = multi(p,p);    }    return ans;}int main(){    LL n;Matrix A = {       1,0,1,       1,0,0,       0,1,0};    int t;    scanf("%d",&t);    while(t--)    {        scanf("%lld",&n);        LL ans;        if(n==2)ans=3;        else if(n==3)ans=4;        else        {Matrix ans1 = power(A,n-4);       ans=(ans1.m[0][0]*6+ans1.m[0][1]*4%MOD+ans1.m[0][2]*3%MOD)%MOD;       /*for(int i=0;i<3;i++)       {           for(int j=0;j<3;j++)            cout<<ans1.m[i][j]<" ";           cout<<endl;       }*/       }       printf("%lld\n",ans);    }    return 0;}


另外也可以这样:
Matrix ans1 = power(A,n+2);
       ans=ans1.m[0][0];
这是把矩阵打出来发现的规律,应该有些什么说法,但我不知道......

0 0
原创粉丝点击