【hdu 5351 MZL's Border 2015多校赛5 】( 高精度 模板)

本文介绍了一种解决斐波那契字符串前m个字符的next值问题的方法,通过高精度计算实现对大整数的操作,并提供了一个完整的C++实现模板。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:f(1)=”a”,f(2)=”b”,f(i)=f(i-1)+f(i-2),”+”表示连接符。给定n,m,求f(n)的前m个字符的“next值”。

分析:打表找到第一个i使M+1<|f(i)| ,答案为 m-|f(i-2)| % MOD
高精度 网上找了一个模板。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <map>
#include <set>
#include <bitset>
#include <cctype>
#include <cstdlib>
#include <queue>
#include <cmath>
#include <stack>
#include <ctime>
#include <string>
#include <vector>
#include <sstream>
#include <functional>
#include <algorithm>
using namespace std;

#define mem(a,n) memset(a,n,sizeof(a))
#define memc(a,b) memcpy(a,b,sizeof(b))
#define rep(i,a,n) for(int i=a;i<n;i++) ///[a,n)
#define dec(i,n,a) for(int i=n;i>=a;i--)///[n,a]
#define pb push_back
#define fi first
#define se second
#define IO ios::sync_with_stdio(false)
#define fre freopen("in.txt","r",stdin)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const double PI=acos(-1.0);
const double eps=1e-8;
const double e=2.7182818;
const int INF=0x3f3f3f3f;
const int MOD=258280327;
const int N=1e3+5;
const ll maxn=5e4;
const int dir[4][2]= {-1,0,1,0,0,-1,0,1};
struct Biginteger
{
    const static int base=1e8;
    const static int len=8;
    typedef vector<int>vec;
    typedef long long ll;
    vec num;
    bool sign;///正负标记 ,1 为负 0为正
    Biginteger()
    {
        num.clear(),sign=0;
    }
    Biginteger(int x)
    {
        sign=0;
        if(x<0)
        {
            sign=1;
            x=-x;
        }
        num.push_back(x%base);
        if(x >= base) num.push_back(x/base);
    }
    Biginteger(bool s,vec x)
    {
        sign=s;
        num=x;
    }
    ///将一个字符串类型转化为大数
    Biginteger(char *s)
    {
        int len = strlen(s),x = 1,sum = 0,f = (s[0]=='-');
        sign = f;
        for(int i=len-1; i>=f; i--)
        {
            sum += (s[i]-'0')*x;
            x *= 10;
            if(x == 1e8 || i == f)
            {
                num.push_back(sum);
                sum = 0;
                x=1;
            }
        }
        while(num.back() == 0 && num.size() > 1)
            num.pop_back();
    }
    ///添加元素
    void push(int x)
    {
        num.push_back(x);
    }
    ///求绝对值
    Biginteger abs()const
    {
        return Biginteger(false,num);
    }
    ///比较大小
    bool smaller(const vec& a,const vec& b)const
    {
        if(a.size() != b.size()) return a.size() < b.size();
        for(int i = a.size()-1; i >= 0; i--)
        {
            if(a[i] != b[i])
                return a[i] < b[i];
        }
        return false;
    }

    bool operator < (const Biginteger &m) const
    {
        if (sign && !m.sign) return true;
        if (!sign && m.sign) return false;
        if (sign && m.sign) return smaller(m.num, num);
        return smaller(num, m.num);
    }
    ///两个大数的 大小比较
    bool operator > (const Biginteger& m)const
    {
        return m < *this;
    }
    ///两个大数 是否相等
    bool operator == (const Biginteger& m)const
    {
        return !(m < *this) && !(*this < m);
    }

    bool operator >= (const Biginteger& m)const
    {
        return !(*this < m);
    }

    bool operator <= (const Biginteger& m)const
    {
        return !(*this > m);
    }
    ///大数相加 a+b
    vec add(const vec& a,const vec& b)const
    {
        vec ans;
        ans.clear();
        int x=0;
        for(int i=0; i<a.size(); i++)
        {
            x += a[i];
            if(i < b.size()) x += b[i];
            ans.push_back(x % base);
            x /= base;
        }
        for(int i=a.size(); i<b.size(); i++)
        {
            x += b[i];
            ans.push_back(x % base);
            x /= base;
        }
        if(x) ans.push_back(x);
        while(ans.back() == 0 && ans.size() > 1)
            ans.pop_back();
        return ans;
    }
    ///大数相减
    vec sub(const vec& a,const vec& b) const
    {
        vec ans;
        ans.clear();
        int x=1;
        for(int i=0; i<b.size(); i++)
        {
            x += base+a[i]-b[i]-1;
            ans.push_back(x % base);
            x /= base;
        }
        for(int i=b.size(); i<a.size(); i++)
        {
            x += base+a[i]-1;
            ans.push_back(x % base);
            x /= base;
        }
        while(ans.back() == 0 && ans.size() > 1)
            ans.pop_back();
        return ans;
    }
    ///大数乘法
    vec mul(const vec &a, const vec &b) const
    {
        vec ans;
        ans.resize(a.size() + b.size());
        for (int i = 0; i < a.size(); i++)
        {
            for (int j = 0; j < b.size(); j++)
            {
                ll tmp = (ll)a[i] * b[j] + ans[i + j];
                ans[i + j + 1] += tmp / base;
                ans[i + j] = tmp % base;
            }
        }
        while (ans.back() == 0 && ans.size() > 1)
            ans.pop_back();
        return ans;
    }
    ///大数除法
    vec div(const vec &a, const vec &b) const
    {
        vec ans(a.size()), x(1, 0), y(1, 0), z(1, 0), t(1, 0);
        y.push_back(1);
        for (int i = a.size() - 1; i >= 0; i--)
        {
            z[0] = a[i];
            x = add(mul(x, y), z);
            if (smaller(x, b)) continue;
            int l = 1, r = base - 1;
            while (l < r)
            {
                int m = (l + r + 1) >> 1;
                t[0] = m;
                if (smaller(x, mul(b, t))) r = m - 1;
                else l = m;
            }
            ans[i] = l;
            t[0] = l;
            x = sub(x, mul(b, t));
        }
        while (ans.back() == 0 && ans.size() > 1)
            ans.pop_back();
        return ans;
    }
    ///重载 加法运算符  两个大数相加
    Biginteger operator + (const Biginteger &m) const
    {
        if (!sign && !m.sign) return Biginteger(false, add(num, m.num));
        if (!sign && m.sign)
        {
            return *this >= m.abs() ?
                   Biginteger(false, sub(num, m.num)) : Biginteger(true, sub(m.num, num));
        }
        if (sign && !m.sign)
        {
            return (*this).abs() > m ?
                   Biginteger(true, sub(num, m.num)) : Biginteger(false, sub(m.num, num));
        }
        return Biginteger(true, add(num, m.num));
    }
    ///重载 减法运算符
    Biginteger operator - (const Biginteger &m) const
    {
        return *this + Biginteger(!m.sign, m.num);
    }
    ///重载 乘法运算符
    Biginteger operator * (const Biginteger &m) const
    {
        Biginteger res(sign ^ m.sign, mul(num, m.num));
        if (res.sign && res.num.size() == 1 && res.num[0] == 0)
            res.sign = false;
        return res;
    }
    ///重载 除法运算符
    Biginteger operator / (const Biginteger &m) const
    {
        if (m == Biginteger(0)) return m;
        Biginteger res(sign ^ m.sign, div(num, m.num));
        if (res.sign && res.num.size() == 1 && res.num[0] == 0)
            res.sign = false;
        return res;
    }
    ///重载 取模运算符
    Biginteger operator % (const Biginteger &m) const
    {
        return *this - *this / m * m;
    }
    void out() const
    {
        if(sign) putchar('-');
        int size = num.size();
        printf("%d",num[size-1]);
        for(int i=size-2; i>=0; i--)
            printf("%08d",num[i]);
        puts("");
    }
};

Biginteger f[N+5];
char s[N];
void init()
{
    f[0]=0,f[1]=f[2]=1;
    for(int i=3;i<=N;i++) f[i]=f[i-1]+f[i-2];
}
int main()
{
    init();
    //for(int i=1;i<10;i++)f[i].out();
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%s",&n,s);
        Biginteger buf(s);
        int mid,lb=1,ub=N;
        while(lb<ub)
        {
            mid=(lb+ub)>>1;
            if(f[mid]>buf+1) ub=mid;
            else lb=mid+1;
        }
        ((buf-f[lb-2])%MOD).out();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值