EOJ1499 矩阵快速幂

本文深入探讨了费拉马数列与高斯求和的巧妙结合,通过数学推导揭示了两者之间的内在联系,并详细介绍了如何利用矩阵快速幂解决特定问题。该文不仅展示了数学思维的精妙,还提供了实用的算法实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

GaussAnd Fibonacci

 

TimeLimit:2000MS Memory Limit:30000KB

TotalSubmit:80 Accepted:38

 

Description

 

Weall know that 1+2+...+n=(1+n)*n/2;Gauss worked it out when he was a child!

Andwe also know the famous number sequence 1,1,2,3,5,8,13... named Fibonaccisequence.(F(1)=F(2)=1;when n>2,F(n)=F(n-1)+F(n-2);)

Ifwe put them togather,what thing will happen?

 

Input

 

Theinput will consist of a series of integers N, one integer per line.Process toend of file.(0<N<1000000000)

 

Output

 

Foreach case,calculate the sum of the Fibonacci numbers who's sequence number isnot bigger than N.Since it can be very huge,you should onle output the lasteight digits,do not output leading zeros(if the answer is 02007729,just output2007729).

 

SampleInput

 

6

 

SampleOutput

 

20

 

Hint:

1+1+2+3+5+8=20

 

Source

 

Modifiyfrom DYGG' problem

 

题目分析:

                   这题还是很考数学思维的。

              S[n-2]=f1+f2+f3+f4+……+fn-2;

              S[n-1]=f1+f2+f3+f4+f5+…fn-1;

              有s[n-1]+s[n-2]=f1+f3+f4+…+fn=s[n]-1;

              有s[n-1]+1+s[n-2]+1=s[n]+1;

              所以有s[n]+1为起点不同的费布拉切数列。观察得是s[n]+1=f(n+2)。难点主要在这个数列的推导上。根据f数列的性质,应该联想到错位相加的,之后利用矩阵快速幂即可算出答案。

 

 

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <string>

#include <vector>

#include <map>

#include <algorithm>

 

using namespace std;

 

struct Matrix

{

    long long a[2][2];

   Matrix(){memset(a,0,sizeof(a));}

};

 

Matrix operator*(const Matrix &a,const Matrix &b)              //矩阵乘法

{

    int i,j,k;

    Matrix c;

    for(i=0;i<2;++i)

        for(j=0;j<2;++j)

            for(k=0;k<2;++k)

            {

                c.a[i][j]=(c.a[i][j]+(a.a[i][k]*b.a[k][j])%100000000)%100000000;

            }

    return c;

}

 

Matrix quick_pow(int n)                        //矩阵快速幂

{

    Matrix ans,tem;

    ans.a[0][0]=ans.a[1][1]=1;

   tem.a[0][1]=tem.a[1][0]=tem.a[1][1]=1;

    while(n)

    {

        if(n&1)

            ans=ans*tem;

        tem=tem*tem;

        n>>=1;

    }

    return ans;

}

 

int main()

{

    int n;

   while(~scanf("%d",&n))

    {

        Matrix ans;

        ans=quick_pow(n+1);

       cout<<(ans.a[0][0]+ans.a[0][1]-1)%100000000<<endl;

    }

    return 0;

}

 

 

 

 

 

 

### 关于EOJ DNA排序问题的解题思路 在处理EOJ中的DNA排序问题时,主要挑战在于如何高效地完成字符串数组的排序以及去重操作。由于题目涉及两个测试点可能因时间复杂度较高而超时,因此需要优化算法设计。 #### 数据结构的选择 为了降低时间复杂度并提高效率,可以引入`std::map`或者`unordered_map`来辅助实现去重功能[^1]。这些数据结构能够快速判断某项是否存在集合中,并支持高效的插入和查找操作。具体来说: - 使用 `std::set` 可以自动去除重复元素并对结果进行升序排列; - 如果还需要自定义比较逻辑,则可以选择基于哈希表的数据结构如 `unordered_set` 配合手动排序。 #### 排序策略 对于给定的一组DNA序列(通常表示为长度固定的字符串),按照字典顺序对其进行排序是一个常见需求。C++标准库提供了非常方便的方法来进行此类任务——即利用 `sort()` 函数配合合适的比较器函数对象或 lambda 表达式来指定所需的排序规则。 下面展示了一个简单的例子用于说明如何读取输入、执行必要的预处理步骤(包括但不限于删除冗余条目),最后输出经过整理的结果列表: ```cpp #include <bits/stdc++.h> using namespace std; int main(){ set<string> uniqueDNAs; string line, dna; while(getline(cin,line)){ stringstream ss(line); while(ss>>dna){ uniqueDNAs.insert(dna); // 自动过滤掉重复项 } } vector<string> sortedUnique(uniqueDNAs.begin(),uniqueDNAs.end()); sort(sortedUnique.begin(),sortedUnique.end()); for(auto it=sortedUnique.cbegin();it!=sortedUnique.cend();++it){ cout<<*it; if(next(it)!=sortedUnique.cend())cout<<" "; } } ``` 上述程序片段实现了基本的功能模块:从标准输入流逐行解析得到各个独立的DNA片段;借助 STL 容器特性轻松达成无重复记录维护目的;最终依据字母大小关系重新安排各成员位置后再统一打印出来[^3]。 #### 学习延伸至自然语言处理领域 值得注意的是,在计算机科学特别是机器学习方向上,“上下文”概念同样重要。例如 Word2Vec 这样的技术就是通过考察周围词语环境来捕捉特定词汇的意义特征[^2]。尽管两者应用场景差异显著,但从原理层面看均体现了对局部模式挖掘的关注。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值