51nod 1491 黄金系统

题目描述

q=(√5+1)/2,在黄金系统下面a0a1…an等于 ni=0aiqni ,其中 ai 是0或者1。
现在给出两个黄金系统下面的数字a和b,请比较他们的大小。
n<=10^5

类斐波那契数

q2=(5+1)2/4=(5+1+25)/4=(3+5)/2=1+(1+5)/2=1+q
所以 n>=2qn=qn2q2=qn2(q+1)=qn1+qn2
根据这个,我们可以设f[i]表示 qi 的系数,初识时,若ai=1则f[n-i]++;若bi=1则f[n-i]–。f[i]的值可以转移到f[i-1]和f[i-2],所以最后我们可以全部转移到f[1]和f[0],就可以比较a和b的大小了(f[1]*q+f[0]>0则a>b)。
直接这样就能过了吗?too naive。
f的值显然可以爆long long。
f是从高位往低位转移的,事实上,在这个过程中当某个f[i]的值的绝对值大于2(也就是高位上第一个f的值的绝对值大于1)且i>2时,a和b大小就已经能够确定了。
假设f[i]=2,因为f[i+1]的绝对值小于等于1,所以f[i-1]的值最小为-1-1=-2,那么f[i]的值转移给f[i-1]和f[i-2]后,f[i-1]>=0,姑且先当f[i-1]=0,而f[i-2]的值最小为-1+2=1,也先当f[i-2]=2(这样保证a是最小的),f[i-2]对后面所有的转态都至少造成了+1的影响,而后面的f>=-1,所以至少有a>=b,而当i>2时,显然可以保证a>b。

代码

#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
#define ll long long
using namespace std;
const int maxn=100000+5;const double p=(sqrt(5)+1)/2;
int f[maxn],l1,l2,i;
char a[maxn],b[maxn];
int main(){
    scanf("%s",a+1);
    scanf("%s",b+1);
    l1=strlen(a+1),l2=strlen(b+1);
    fo(i,1,l1) f[l1-i]=a[i]-'0';
    fo(i,1,l2) f[l2-i]+='0'-b[i];
    fod(i,max(l1,l2),3){
        if (f[i]<-1) {printf("<\n");return 0;}
        if (f[i]>1) {printf(">\n");return 0;}
        f[i-1]+=f[i],f[i-2]+=f[i];
    }
    f[1]+=f[2],f[0]+=f[2];
    if (f[1]==0&&f[0]==0) {printf("=\n");return 0;}
    double s=f[1]*p+f[0];
    if (s>0) printf(">\n");else printf("<\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值