2017中國大學生程序設計競賽 - 女生專場 Happy Necklace(遞推+矩陣快速冪)

Happy Necklace

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1146    Accepted Submission(s): 491


php

Problem Description
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 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 modulo .
Note: The necklace is a single string, {not a circle}.
 


Input
The first line of the input contains an integer , denoting the number of test cases.
For each test case, there is a single line containing an integer , denoting the number of beads on the necklace.
 


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


Sample Input
 
 
223
 

 

Sample Output
 
 
34
 

 

Source
題目描述:你有一個有n個顏色爲紅色或藍色的珠子的項鍊,你能夠將項鍊截斷成長度爲素數的珠子,若是截取出的一段紅色的珠子的個數大於藍色的珠子,則成爲good,問一共有多少種good的可能性。
    能夠發現
    n=2,res=3;n=3,res=4;n=4,res=6;n=5,res=9;
    故有遞推式 An=An-1+An-3;

    若是用a表示紅色,用b表示藍色。題意明顯能夠看出只須要管長度2和3的連續序列是否符合!ios

    若是以b結尾,那麼下一個必須是a,或者加個aab就能夠了!app

 

    因此同理就能夠推出遞推式An=An-1+An-3;
    看一下題目的數據範圍,n最大1e18,所以常規O(n)的遞推顯然不可行,所以直接上O(logn)的矩陣快速冪。

 

 

    發現遞推式是四階的遞推式,故所得的常數矩陣應該是四維的。以後只需帶入矩陣快速冪模板便可。

先看這個特徵方程F[i] = F[i - 1] + F[i - 3],那麼就有一個矩陣以下less

咱們的目標矩陣就是ui

那麼,針對這個矩陣咱們如何轉置呢?spa

先看目標矩陣第一個:F[i]設計

F[i] = F[i - 1] + F[i - 3]code

那麼,由矩陣乘法,轉置矩陣第一行,彷佛就定了:1 0 1blog

一樣的,二三行就是1 0 0 和 0 1 0ip

整個矩陣以下:

 

#include<iostream>  
#include<algorithm>  
#include<cmath>  
#include<cstdio>  
#include<cstring>  
  
#define INF 0x3f3f3f3f  
  
#define mod 1000000007  
  
using namespace std;  
  
typedef long long ll;  
const int maxn = 100010;  
  
ll n;  
  
struct Matrix {  
    ll a[5][5];  
};  
  
  
Matrix mul(Matrix x, Matrix y)  
{  
    Matrix temp;  
    for (int i = 1; i <= 3; i++)  
        for (int j = 1; j <= 3; j++) temp.a[i][j] = 0;  
  
    for (int i = 1; i <= 3; i++)  
    {  
        for (int j = 1; j <= 3; j++)  
        {  
            ll sum = 0;  
            for (int k = 1; k <= 3; k++)  
            {  
                sum = (sum + x.a[i][k] * y.a[k][j] % mod) % mod;  
            }  
            temp.a[i][j] = sum;  
        }  
    }  
    return temp;  
}  
  
Matrix quickpow(Matrix A,ll k)  
{  
    Matrix res;  
    res.a[1][1] = 1; res.a[1][2] = 0; res.a[1][3] = 0;  
    res.a[2][1] = 0; res.a[2][2] = 1; res.a[2][3] = 0;  
    res.a[3][1] = 0; res.a[3][2] = 0; res.a[3][3] = 1;  
    while (k)  
    {  
        if (k & 1) res = mul(res, A);  
        A = mul(A, A);  
        k >>= 1;  
    }  
    return res;  
}  
  
int main()  
{  
    int t;  
    scanf("%d", &t);  
    while (t--)  
    {  
        scanf("%lld", &n);  
        if (n == 2)  
        {  
            printf("3\n");  
            continue;  
        }  
        Matrix A;  
        A.a[1][1] = 1; A.a[1][2] = 0; A.a[1][3] = 1;  
        A.a[2][1] = 1; A.a[2][2] = 0; A.a[2][3] = 0;  
        A.a[3][1] = 0; A.a[3][2] = 1; A.a[3][3] = 0;  
        Matrix res = quickpow(A, n - 2);  
        ll x = (res.a[1][1] + res.a[1][2] + res.a[1][3]) % mod;  
        ll y = (res.a[2][1] + res.a[2][2] + res.a[2][3]) % mod;  
        ll z = (res.a[3][1] + res.a[3][2] + res.a[3][3]) % mod;  
        printf("%lld\n", (x + y + z) % mod);  
    }  
}  
相關文章
相關標籤/搜索