Log Concave Sequences 【Gym - 102302H】【矩阵快速幂】

Log Concave Sequences

 Gym - 102302H


  题目中说到,对于每个1<i<N,有\large a_{i - 1} * a_{i + 1} \leq a_i ^ {2},于是乎,我们可以看成是多个三元组的合并了。

  那么,又该如何去计算答案呢?我们不妨看成多个基础三元组的方案了,\large i-j-k这样的形式,有\large i * K \leq j^2,于是方便与去构造这样的方案,我们可以看成i到j和j到k两条路,于是就是通过路径来求解了。

  我们看成路径\large i-j\large j-k于是,我们哈希第一条路径,因为他们的值是0~2的,所以我们将第一条路径哈希成为\large 3 * i + j同理,将第二条路径哈希成为\large 3 * j + k,于是我们就可以用一个9*9的矩阵(0~8)*(0~8)大小,来求解当长度为N时候的方案数了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const ll mod = 1e9 + 7;
struct matrice
{
    ll a[9][9];
    matrice() { memset(a, 0, sizeof(a)); }
    friend matrice operator * (matrice x, matrice y)       //重载函数,矩阵的乘积得到的新矩阵
    {
        matrice ans;
        for(int i=0; i<9; i++)
        {
            for(int j=0; j<9; j++)
            {
                ll tmp = 0;
                for(int k=0; k<9; k++)
                {
                    tmp = (tmp + x.a[i][k] * y.a[k][j] % mod) % mod;       //最后得到的需要取mod
                }
                ans.a[i][j] = tmp;
            }
        }
        return ans;
    }
}Bas;
matrice Fast_Mi(matrice x, ll ti)
{
    matrice ans;
    for(int i=0; i<9; i++) ans.a[i][i] = 1;  //构造单位阵
    while(ti)
    {
        if(ti & 1LL) ans = ans * x;
        x = x * x;
        ti >>= 1LL;
    }
    return ans;
}
ll N, ans;
int main()
{
    for(int i=0; i<=2; i++) for(int j=0; j<=2; j++) for(int k=0; k<=2; k++) if(i * k <= j * j) Bas.a[3 * i + j][3 * j + k] = 1;
    scanf("%lld", &N);
    Bas = Fast_Mi(Bas, N - 2LL);
    for(int i=0; i<9; i++) for(int j=0; j<9; j++) ans = (ans + Bas.a[i][j]) % mod;
    printf("%lld\n", ans);
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值