Skip to content

泉州一中信息学Blog

信息学奥赛技术分享博客

  • 登录
  • 小学oj
  • 中学oj
  • 测试页面1
  • Toggle search form

21 Days Training // Day 13

Posted on 2025年8月7日 By c2022zyh 21 Days Training // Day 13无评论

T0. math

My idea :

Let f(n)=x^n+x^{-n} . Notice that f(1)=k
And when 2 \mid n , f^2(\frac{n}{2}) = (x^{\frac{n}{2}}+x^{-\frac{n}{2}})^2=x^n+x^{-n}+2x^{\frac{n}{2}}x^{-\frac{n}{2}} = f(n)+2 .
Therefore, 2 \mid n , f(n) = f^2(\frac{n}{2})-2 .

Based on this formula, we can get f(n) withb a complexity of O(\log_2 n) .

Bug :

When 2 \nmid n , f^2(\frac{n-1}{2}) = f(n-1)-2 .
Now we need to solve f(n-1) .

But, currently, I found this formula : f(n-1)f(1) = (x^{n-1}+x^{-n+1})(x+x^{-1}) = x^n + x^{-n} + x^{n-2} + x^{-n+2} = f(n) + f(n-2) .

Therefore, f(n) = f(n-1)f(1)-f(n-2) .
If we directly use above idea to solve it, the complexity will be O(n) , TLE.

(Right) idea :

Actually, we are colse enough to the answer.
Notice that f(1) is a given constant k .
So the equation will be f(n) = kf(n-1)-f(n-2) .
Seems familiar?
When we meet such formula… we can use matrix!

T0-EX. Matrix qkp Extension

Did you still remember this passage ?
There, we show the example of solving fibonacci numbers with matrix.
In fact, it can be used in such problems.

Thing about the form of the matrix :

And how we get M^{N+1} :

Here, we designed a matrix M so that it satisfies those properties above.

However, the generalize this method, we face 2 problems :

  1. Sometimes the initial condition not equals to M.
  2. Sometimes the coefficient changes, maybe (2, 3), (5, 8), (114514, 191981).

For the first problem, just change the formula : M^N into M_0 \times M^N .

Here, M_0 is the initial status of the sequence, M shows the relations between these terms in the sequence.

For the second problem, go back to the equation.

Suppose that we have a sequence that satisfies $AN = pA{N-1} + qA_{N-2}$ .

And we have calculated

Now we expected to get M_0 \times M^{N+1} by calculating :

By comparing the terms, we can get :

By comparing the coefficients, we can get :

So the matrix M is :

To initialize, the matrix M_0 should be :

So, based on M_0 and M , we can solve the sequence quickly!

T0. math (Part II)

If you read the prev. page carefully, you must know how to use the conclusion.

Go back to the formula f(n) = kf(n-1)-f(n-2) .
If we consider f(n) as an element of a sequence, just set p=k, q=-1 , we can solve f(n) by matrix qkp.

Code :

#include <bits/stdc++.h>
using namespace std;
typedef vector<long long> V1D;
typedef vector<V1D> V2D;

class Matrix {
    private:
        V2D value;
        long long MH, MW;
    public :
        // Matrix() {}
        Matrix(V2D Vec) {value=Vec;MH=Vec.size(), MW=Vec[0].size();}
        Matrix(long long H, long long W) {
            MH=H, MW=W;
            for (long long i=0;i<H;i++) value.push_back(V1D(W));
        }
        long long getHeight() {return MH;}
        long long getWidth() {return MW;}
        long long getValue(long long y, long long x) {return value[y][x];}
        void change(long long y, long long x, long long v) {value[y][x] = v;}
        V2D matrixVec() {return value;}
        Matrix operator+(Matrix Mx) {
            long long Hx=Mx.getHeight(), Wx=Mx.getWidth();
            if (Hx != MH || Wx != MW) {
                cout << "Matrix Exception (operator+, E1) : Size not equal.";
                exit(0);
            }
            Matrix Mr(MH, MW);
            for (long long i=0;i<MH;i++) {
                for (long long j=0;j<MW;j++) Mr.change(i, j, value[i][j]+Mx.getValue(i, j));
            }
            return Mr;
        }
        Matrix operator-(Matrix Mx) {
            long long Hx=Mx.getHeight(), Wx=Mx.getWidth();
            if (Hx != MH || Wx != MW) {
                cout << "Matrix Exception (operator-, E2) : Size not equal.";
                exit(0);
            }
            Matrix Mr(MH, MW);
            for (long long i=0;i<MH;i++) {
                for (long long j=0;j<MW;j++) Mr.change(i, j, value[i][j]-Mx.getValue(i, j));
            }
            return Mr;
        }
        Matrix operator*(Matrix Mx) {
            long long Hx=Mx.getHeight(), Wx=Mx.getWidth();
            if (MW!=Hx) {
                cout << "Matrix Exception (operator*, E3) : Illegal H/W.";
                exit(0);
            }
            Matrix Mr(MH, Wx);
            for (long long i=0;i<MH;i++) {
                for (long long j=0;j<Wx;j++) {
                    long long cur=0;
                    for (long long k=0;k<MW;k++) cur += value[i][k] * Mx.getValue(k, j);
                    Mr.change(i, j, cur);
                }
            }
            return Mr;
        }
        Matrix operator%(long long MOD) {
            Matrix Mr(value);
            for (long long i=0;i<MH;i++) {
                for (long long j=0;j<MW;j++) Mr.change(i, j, Mr.getValue(i, j)%MOD);
            }
            return Mr;
        }
};

Matrix UnitMatrix(long long K) {
    Matrix M0(K, K);
    for (long long i=0;i<K;i++) M0.change(i, i, 1);
    return M0;
};

Matrix qkMpow(Matrix Mx, long long e, long long MOD) {
    long long K = Mx.getHeight();
    if (e==0) return UnitMatrix(K);
    if (e==1) return Mx;
    Matrix HF = qkMpow(Mx, e/2, MOD);
    if (e&1) return ((HF*HF)*Mx)%MOD;
    return (HF*HF)%MOD;
};

int main() {
    long long N, K, MD;cin >> MD >> K >> N;
    Matrix M0(2, 2), MP(2, 2);
    M0.change(0, 0, 2);
    M0.change(0, 1, K);
    M0.change(1, 0, K);
    M0.change(1, 1, ((K*K)%MD-2+MD)%MD);
    MP.change(0, 1, -1);
    MP.change(1, 0, 1);
    MP.change(1, 1, K);
    Matrix Mx = qkMpow(MP, N, MD);
    Matrix M = M0*Mx;
    V2D Vec = M.matrixVec();
    cout << (Vec[0][0]+MD)%MD;

    return 0;
}

Note :
Because the coefficient q is negative, when get the result, add it by MD and modulo it again.

This code can correctly answer all samples.
Not all cases!

Pages: 1 2 3
训练日志

文章导航

Previous Post: 中山集训8.7
Next Post: 2025暑假中山集训Day13——8.07

发表回复 取消回复

要发表评论,您必须先登录。

2025年 12月
一 二 三 四 五 六 日
1234567
891011121314
15161718192021
22232425262728
293031  
« 8月    

2024常州 Class Classic OI Problems Contest cqr的长乐集训2023 CZYZ LOC New Game NOI NOIP Password Protected PM_PK Preview Problems Retrospect Selfmade Qusetion STL The end Training Uneasy Problem 蒟蒻 通报

  • 训练日志
  • 链表
  • 入门
  • 模拟
  • dfs序
  • 并查集
  • spfa
  • 最小割
  • 矩阵树定理
  • 仙人掌
  • BSGS
  • 凸包
  • 回文自动机
  • 递推与动归
  • 堆
  • 莫队算法
  • ST表
  • Treap
  • 树套树
  • 可持久化线段树
  • 初赛
  • 搜索
  • 贪心
  • 深度优先搜索
  • 欧拉图
  • dijkstra
  • 费用流
  • 哈夫曼树
  • kruskual
  • 置换
  • 旋转卡壳
  • KMP
  • 区间动归
  • STL
  • 链表
  • 可并堆
  • sply
  • 主席树
  • 可持久化字典树
  • 算法
  • 动态规划
  • 构造
  • 广度优先搜索
  • 最短路
  • floyd
  • 最大流
  • 虚树
  • prim
  • 筛法
  • 半平面交
  • 字典树
  • 背包动归
  • 基础数据结构
  • 分块
  • 线段树
  • 替罪羊树
  • K-DTree
  • 图论
  • 二分法
  • 迭代搜索
  • 拓扑排序
  • 有上下界网络流
  • 生成树
  • 快速幂
  • 后缀数组
  • 树形动归
  • 哈希表
  • 中级数据结构
  • 平衡树
  • 可持久化数据结构
  • 数据结构
  • 三分法
  • 启发式搜索
  • 图的连通
  • 点分治
  • 博弈论
  • AC自动机
  • 状压动归
  • 单调栈
  • 树状数组
  • 高级数据结构
  • OI资料
  • 数学
  • 高精度
  • 差分约束
  • 树上倍增
  • 素数测试
  • 后缀自动机
  • 数位动归
  • 单调队列
  • 新闻
  • 几何
  • 随机化
  • 二分图染色
  • 树链剖分
  • 欧拉函数
  • manacher
  • 斜率优化
  • 离线处理
  • 信息学奥赛学长风采
  • 字符串
  • 二分图匹配
  • prufer编码
  • 卡特兰数
  • 密码学
  • 决策单调
  • 赛后总结
  • 其他
  • 2-SAT
  • 最近公共祖先
  • 矩阵乘法
  • 记忆化搜索
  • 网络流
  • Link cut tree
  • 排列组合
  • 树
  • 高斯消元
  • 乘法逆元
  • 容斥原理
  • 调和级数
  • 概率与期望
  • 模线性方程组
  • 莫比乌斯反演
  • 快速傅里叶变换
  • 扩展欧几里德
  • 最大公约数与最小公倍数

近期文章

  • 中山纪念中学 Day21
  • 中山集训8.15 LAST DAY+集训小结
  • GDNOJ – DAY 18
  • 中山8.14
  • 2025暑假中山集训Day20——8.14

近期评论

归档

  • 2025年8月
  • 2025年7月
  • 2025年2月
  • 2025年1月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月

Copyright © 2025 泉州一中信息学Blog.

Powered by PressBook WordPress theme