51nod 算法马拉松6(索函数)(规律题目)

本文介绍了一种利用斐波那契数列求解特定问题的方法,通过对数转换简化计算过程,并提供了详细的数学归纳法证明及C++实现代码。

总的来说是要先找规律的题目,然后就是一个球log2(f[ n ])的技巧。

这题目的解题报告说的很详细:

通过列出前几项观察可以发现,答案其实是2^k-1,其中k为fib[n]在二进制表示中的位数,记为bit(f[n])。

下面来证明该结论。用数学归纳法。

对于m=0,1时该结论显然成立。设当m<n时成立。

当m=n时,

由于f[n]=f[n-1]+f[n-2]那么这个时候bit[f[n]]要么等于bit(f[n-1])要么等于bit(f[n-1])+1。

当bit(f[n])==bit(f[n-1])时,Sor(n)=Sor(n-1)=2^(bit(f[n-1]))-1,结论成立。

当bit(f[n])==bit(f[n-1])+1时,Sor(n)=Sor(n-1)*2+1=2^(bit(f[n-1])+1)-1=2^(bit(f[n]))-1,结论成立。

所以原结论成立。

由于n比较大,直接计算位数出不来。可以通过取对数来解决。

由斐波那切的通项公式F[n]=(((1+sqrt(5))/2)^n-((1-sqrt(5))/2)^n)/sqrt(5)= (((1+sqrt(5))/2)^n/sqrt(5))*(1-((1-sqrt(5))/(1+sqrt5))^n)

F[n]在二进制下的位数是(int)log2((((1+sqrt(5))/2)^n/sqrt(5))*(1-((1-sqrt(5))/(1+sqrt5))^n))+1

当n比较的时候直接暴力计算出位数即可。

当n比较大的时候由于(1-((1-sqrt(5))/(1+sqrt5))^n))=1

那么计算(int)log2((((1+sqrt(5))/2)^n/sqrt(5))+1这个即可。

把n提前面来就可以O(1)计算,(int)(n*log2((1+sqrt(5)) /2)- log2(sqrt(5)))+1

最后用快速幂取余计算出结果。

#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define rep1(i,x,y) for(int i=x;i<=y;i++)

typedef long long ll;
typedef unsigned long long llu;
const ll base = (ll)1e17;
const int N = 1e5 + 100;
const int mod = 1e9 + 7;
const ll tbase = base%mod;

int bit_(llu n){ return (int)log2(n) + 1 ;}
llu f[N],d[N],lim = 83 , yu[N];
void init(){
   f[0] = 0;f[1] = 1; yu[0] = 1;
   d[0] = 0; d[1] = 1;
   for(int i=1;i<=100;i++) yu[i] = yu[i-1]*2%mod;
   for(int i=2;;i++){
       f[i] =f[i-1]+f[i-2];
       d[i] = (yu[bit_(f[i])]-1+mod)%mod;
       if(f[i] > base){
           break;
       }
   }
}
ll n;
ll pow_(ll a, ll b){
   ll ans = 1 , te = a;
   while(b){
       if(b&1) ans = ans*te%mod;
       b>>=1;
       te=te*te%mod;
   }
   return ans;
}
inline ll read(ll& n){
   n = 0; int ch = getchar();
   while(!isdigit(ch)) ch=getchar();
   while(isdigit(ch)) n = n*10 + ch-'0' , ch=getchar();
}
int main()
{
   init();
   int T;
   scanf("%d",&T);
   while(T--){
      read(n);
      if(n < 80)
        printf("%d\n",(int)d[n]);
      else {
         long long res = (ll)((double)n*log2((1+sqrt(5))/2)- log2(sqrt(5)))+1;
         printf("%d\n",(int)((pow_(2,res)-1+mod)%mod));
      }
   }
   return 0;
}



基于STM32 F4的永磁同步电机无位置传感器控制策略研究内容概要:本文围绕基于STM32 F4的永磁同步电机(PMSM)无位置传感器控制策略展开研究,重点探讨在不依赖物理位置传感器的情况下,如何通过算法实现对电机转子位置和速度的精确估计与控制。文中结合嵌入式开发平台STM32 F4,采用如滑模观测器、扩展卡尔曼滤波或高频注入法等先进观测技术,实现对电机反电动势或磁链的估算,进而完成无传感器矢量控制(FOC)。同时,研究涵盖系统建模、控制算法设计、仿真验证(可能使用Simulink)以及在STM32硬件平台上的代码实现与调试,旨在提高电机控制系统的可靠性、降低成本并增强环境适应性。; 适合人群:具备一定电力电子、自动控制理论基础和嵌入式开发经验的电气工程、自动化及相关专业的研究生、科研人员及从事电机驱动开发的工程师。; 使用场景及目标:①掌握永磁同步电机无位置传感器控制的核心原理与实现方法;②学习如何在STM32平台上进行电机控制算法的移植与优化;③为开发高性能、低成本的电机驱动系统提供技术参考与实践指导。; 阅读建议:建议读者结合文中提到的控制理论、仿真模型与实际代码实现进行系统学习,有条件者应在实验平台上进行验证,重点关注观测器设计、参数整定及系统稳定性分析等关键环节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值