uva8455 Twice Equation(pell方程+高精度)

题目好神啊orz
给sbw巨佬跪烂
n(n+1)=2m(m+1) ,使得有正整数解m的最小的n,要求n>=l。
我们化一下这个等式:
4n2+4n+2=8m2+8m+2
(2n+1)2+1=2(2m+1)2
x=2n+1,y=2m+1
x22y2=1
这就是个pell方程的形式2了。
我们有一组基本解 x0=1,y0=1 ,可以递推得到 xn=6xn1xn2,x0=1,x1=7
需要一系列高精。
我的这份代码在计蒜客上a了。然而uva t了。我也不知道为什么qaq

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 200
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,tst,tot=250;
char s[N];
struct bigint{
    int a[N],n;
    bigint(){memset(a,0,sizeof(a));n=0;}
    friend bigint operator*(bigint a,int x){
        bigint res;res.n=a.n;
        for(int i=1;i<=res.n;++i) res.a[i]=a.a[i]*x;
        for(int i=1;i<=res.n;++i) res.a[i+1]+=res.a[i]/10,res.a[i]%=10;
        while(res.a[res.n+1]) res.n++,res.a[res.n+1]+=res.a[res.n]/10,res.a[res.n]%=10;
        return res;
    }friend bigint operator-(bigint a,bigint b){
        bigint res;res.n=a.n;
        for(int i=1;i<=res.n;++i) res.a[i]=a.a[i]-b.a[i];
        for(int i=1;i<=res.n;++i) if(res.a[i]<0) res.a[i]+=10,res.a[i+1]--;
        while(!res.a[res.n]) --res.n;return res;
    }friend bigint operator/(bigint a,int x){
        bigint res;res.n=a.n;int tmp=0;
        for(int i=res.n;i>=1;--i){
            tmp=tmp*10+a.a[i];res.a[i]=tmp/x;tmp%=x;
        }while(!res.a[res.n]) --res.n;return res;
    }friend bool operator<(bigint a,bigint b){
        if(a.n<b.n) return 1;
        if(a.n>b.n) return 0;
        for(int i=a.n;i>=1;--i){
            if(a.a[i]<b.a[i]) return 1;
            if(a.a[i]>b.a[i]) return 0;
        }return 0;
    }
}a[310],b;
int main(){
//  freopen("data.in","r",stdin);
//  freopen("a.out","w",stdout);
    a[0].n=1;a[0].a[1]=1;a[1].n=1;a[1].a[1]=7;
    for(int i=2;i<=tot;++i) a[i]=a[i-1]*6-a[i-2];
    for(int i=1;i<=tot;++i) a[i]=a[i]/2;
    while(~scanf("%d",&tst)){ 
        while(tst--){
            scanf("%s",s+1);
            n=strlen(s+1);b.n=n;
            for(int i=1;i<=n;++i) b.a[i]=s[n-i+1]-'0';
            for(int i=1;i<=tot;++i){
                if(a[i]<b) continue;
                for(int j=a[i].n;j>=1;--j) putchar(a[i].a[j]+'0');puts("");break;
            }
        }
    }return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值