高精度算法进阶

填之前的坑。。

@

前言

其实也没啥写的,提高组的进阶高精也就高精除高精了(若是想到其他的以后再补)。
至于高精开根这些以后省选再写(退役flag高高立起)

思路

采用二分,mid*高精小数与高精大数做 \(\leq\) 的比较
时间\(O(n\log n)\),答案int范围内\(\log\)是30多一点,常数写好就不怕
(至少比一个一个减要好吧

还有我不会压位,之后再补(挖坑中)

代码

luoguP2005 136ms
常数按正常休闲写法写的,跑的还算快
程序中变量名和函数名都hin形象,将就看吧
(我对我的码风还是挺有信心的)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int read(){
    int x=0;int pos=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;;
    for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
    return pos?x:-x; 
}
struct bigint{
    long long len,num[25001];
};
int comp_less(bigint a,bigint b){
    if(a.len<b.len) return 1;
    else if(a.len>b.len) return 0;
    else{
        for(int i=1;i<=a.len;i++){
            if(a.num[i]<b.num[i]) return 1;
        }
        return 0;
    }
}
int comp_less_or_equl(bigint a,bigint b){
    if(a.len<b.len) return 1;
    else if(a.len>b.len) return 0;
    else{
        for(int i=1;i<=a.len;i++){
            if(a.num[i]>b.num[i]) return 0;
            else if(a.num[i]<b.num[i]) return 1;
        }
        return 1;
    }
}
char s1[25001],s2[25001];int tans[25001],top;
bigint mul(bigint a,int b){
    bigint ans;
    ans.len=0;
    long long tmp=0;top=0;
    for(int i=a.len;i>=1;i--){
        tmp+=a.num[i]*b;
        tans[++top]=tmp%10;
        tmp/=10;
    }
    while(tmp){
        tans[++top]=tmp%10;
        tmp/=10;
    } 
    ans.len=top;
    for(int i=1;i<=top;i++){
        ans.num[i]=tans[top-i+1]; 
    }
    return ans;
}
long long div(bigint a,bigint b){
    long long l=1,r=2000000001,mid;
    while(l<r-1){
        mid=(l+r)>>1;
        if(comp_less_or_equl(mul(b,mid),a)) l=mid;
        else r=mid;
        //printf("%lld %lld %lld\n",l,r,mid);
    }
    return l;
}
int main(){
    scanf("%s",s1);
    scanf("%s",s2);
    int l1=strlen(s1),l2=strlen(s2);
    bigint a1,a2;a1.len=l1,a2.len=l2;
    for(int i=0;i<l1;i++){
        a1.num[i+1]=s1[i]-'0';
    }
    for(int i=0;i<l2;i++){
        a2.num[i+1]=s2[i]-'0';
    }
    if(comp_less(a1,a2)){
        printf("0");
        return 0;
    }
    printf("%lld",div(a1,a2));
    return 0;
}
posted @ 2019-07-27 22:58  lcyfrog  阅读(111)  评论(0编辑  收藏  举报