https://www.luogu.com.cn/problem/P1487
一个长度为 (n) 的序列,已知 (A_1,A_n,n,d),并满足 (A_i=dfrac{A_{i-1}+A_{i+1}}{2}+d),求 (A_m)
最近数学课学了点特征方程,所以用它做了下这题
一般用特征方程求通项的时候,是已知数列满足 (a_{i+1}+Ba_i+Ca_{i-1}=0)
那么设 (a_{n+1}-pa_n=q(a_n-pa_{n-1})),转化成 (a_{n+1}-(p+q)a_n+pqa_{n-1}=0)
此时应满足 (p+q=-B,pq=C)
然后用韦达定理构造一个两个解分别是 (p,q) 的二次方程并把它解出来,就知道 (p,q) 了
如果无解当然就是不能这样构造
进而设 (b_n=a_{n+1}-pa_n),则:
同时除以 (p^{n+1}),就是:
再设 (c_n=dfrac{a_n}{p^n})
就可以表示成:
那么对 (c) 做一个累加,中间的一堆项就消没了,得到:
一通整理,发现从里面把与求和无关的因式提出来,就是个等比数列,用一下求和公式,于是:
还原成 (a_n),就是:
也许能再化简让形式更好看一些?但我懒得化了
再看这个题
发现这个 (2d) 很耽误事,但是可以设 (a_i=A_i+d),于是:
按照之前讲的,此时应满足 (p+q=-2,pq=-1),于是构造方程 (x^2+2x-1=0)
两个解对应 (p,q),也就是 (p=sqrt{2}-1,q=-sqrt{2}-1),当然把它们的值互换也不会对结果产生影响
但我们并不知道 (a_n) 表达式里的 (a_2) 是什么,但是知道 (a_n),于是可以变一下那个式子把 (a_2) 求出来:
然后就可以带入 (n=m) 来求出答案了
注意判断一下 (m=0) 这种奇怪的情况
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline long double power(long double a,int b){
long double ret=1;
while(b--) ret*=a;
return ret;
}
int main(){
int n,m;scanf("%d%d",&n,&m);
if(!m) return puts("0.000"),0;
long double d,A1,An,a1,an,a2,am,Am;scanf("%Lf%Lf%Lf",&d,&A1,&An);
a1=A1-d;an=An-d;
long double p=std::sqrt(2)-1,q=-std::sqrt(2)-1;
a2=(q/p-1)*(an-a1*power(p,n-1))/(power(q,n-1)/p-power(p,n-2))+p*a1;
am=(power(q,m-1)/p-power(p,m-2))*(a2-p*a1)/(q/p-1)+a1*power(p,m-1);
Am=am+d;
printf("%.3Lf",Am);
return 0;
}