bzoj 1002 找规律(基尔霍夫矩阵)

本文介绍了一种使用高精度计算解决特定递推数列问题的方法。通过定义递推公式 w[i]=3*w[i-1]-w[i-2]+2,并实现加法和减法的高精度计算函数,最终实现了对数列第 n 项的高效求解。

  网上说的是什么基尔霍夫矩阵,没学过这个,打个表找下规律,发现

w[i]=3*w[i-1]-w[i-2]+2;

然后写个高精直接递推就行了

//By BLADEVIL
var
    n                    :longint;
    a, b, c                :array[0..100000] of longint;
    w                    :array[0..200] of ansistring;
    i                    :longint;
    
function plus(s1,s2:ansistring):ansistring;
var
    len                    :longint;
    i                    :longint;
    s                    :ansistring;
    
begin
    fillchar(a,sizeof(a),0);
    fillchar(b,sizeof(b),0);
    fillchar(c,sizeof(c),0);
    len:=length(s1);
    for i:=1 to len do a[(len-i) div 4+1]:=a[(len-i) div 4+1]*10+ord(s1[i])-48;
    len:=length(s2);
    for i:=1 to len do b[(len-i) div 4+1]:=b[(len-i) div 4+1]*10+ord(s2[i])-48;
    if length(s1)>len then len:=length(s1);
    len:=(len+3) div 4;
    for i:=1 to len do
    begin
        c[i]:=c[i]+a[i]+b[i];
        c[i+1]:=c[i+1]+c[i] div 10000;
        c[i]:=c[i] mod 10000;
    end;
    inc(len);
    plus:='';
    for i:=len downto 1 do 
    begin
        str(c[i],s);
        if c[i]<1000 then plus:=plus+'0';
        if c[i]<100 then plus:=plus+'0';
        if c[i]<10 then plus:=plus+'0';
        plus:=plus+s;
    end;
    while (plus[1]='0') and (length(plus)>1) do delete(plus,1,1);
end;
    
function jian(s1,s2:ansistring):ansistring;
var
    len                    :longint;
    i                    :longint;
    s                    :ansistring;
begin
    fillchar(a,sizeof(a),0);
    fillchar(b,sizeof(b),0);
    fillchar(c,sizeof(c),0);
    len:=length(s1);
    for i:=1 to len do a[(len-i) div 4+1]:=a[(len-i) div 4+1]*10+ord(s1[i])-48;
    len:=length(s2);
    for i:=1 to len do b[(len-i) div 4+1]:=b[(len-i) div 4+1]*10+ord(s2[i])-48;
    len:=(length(s1)+3) div 4;
    for i:=1 to len do c[i]:=a[i]-b[i];
    for i:=1 to len do if c[i]<0 then  
    begin
        c[i]:=c[i]+10000;
        dec(c[i+1]);
    end;
    jian:='';
    for i:=len downto 1 do
    begin
        str(c[i],s);
        if c[i]<1000 then jian:=jian+'0';
        if c[i]<100 then jian:=jian+'0';
        if c[i]<10 then jian:=jian+'0';
        jian:=jian+s;
    end;
    while (jian[1]='0') and (length(jian)>1) do delete(jian,1,1);
end;
    
begin
    read(n);
    w[1]:='1'; w[2]:='5';
    for i:=3 to n do 
        w[i]:=plus(jian(plus(plus(w[i-1],w[i-1]),w[i-1]),w[i-2]),'2');
    writeln(w[n]);
end.

 

转载于:https://www.cnblogs.com/BLADEVIL/p/3438639.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值