天天看点

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

题意: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(-);
const double eps=;
const double e=;
const int INF=;
const int MOD=;
const int N=+;
const ll maxn=;
const int dir[][]= {-,,,,,-,,};
struct Biginteger
{
    const static int base=;
    const static int len=;
    typedef vector<int>vec;
    typedef long long ll;
    vec num;
    bool sign;///正负标记 ,1 为负 0为正
    Biginteger()
    {
        num.clear(),sign=;
    }
    Biginteger(int x)
    {
        sign=;
        if(x<)
        {
            sign=;
            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 = ,sum = ,f = (s[]=='-');
        sign = f;
        for(int i=len-; i>=f; i--)
        {
            sum += (s[i]-'0')*x;
            x *= ;
            if(x ==  || i == f)
            {
                num.push_back(sum);
                sum = ;
                x=;
            }
        }
        while(num.back() ==  && num.size() > )
            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()-; i >= ; 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=;
        for(int i=; 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() ==  && ans.size() > )
            ans.pop_back();
        return ans;
    }
    ///大数相减
    vec sub(const vec& a,const vec& b) const
    {
        vec ans;
        ans.clear();
        int x=;
        for(int i=; i<b.size(); i++)
        {
            x += base+a[i]-b[i]-;
            ans.push_back(x % base);
            x /= base;
        }
        for(int i=b.size(); i<a.size(); i++)
        {
            x += base+a[i]-;
            ans.push_back(x % base);
            x /= base;
        }
        while(ans.back() ==  && ans.size() > )
            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 = ; i < a.size(); i++)
        {
            for (int j = ; j < b.size(); j++)
            {
                ll tmp = (ll)a[i] * b[j] + ans[i + j];
                ans[i + j + ] += tmp / base;
                ans[i + j] = tmp % base;
            }
        }
        while (ans.back() ==  && ans.size() > )
            ans.pop_back();
        return ans;
    }
    ///大数除法
    vec div(const vec &a, const vec &b) const
    {
        vec ans(a.size()), x(, ), y(, ), z(, ), t(, );
        y.push_back();
        for (int i = a.size() - ; i >= ; i--)
        {
            z[] = a[i];
            x = add(mul(x, y), z);
            if (smaller(x, b)) continue;
            int l = , r = base - ;
            while (l < r)
            {
                int m = (l + r + ) >> ;
                t[] = m;
                if (smaller(x, mul(b, t))) r = m - ;
                else l = m;
            }
            ans[i] = l;
            t[] = l;
            x = sub(x, mul(b, t));
        }
        while (ans.back() ==  && ans.size() > )
            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() ==  && res.num[] == )
            res.sign = false;
        return res;
    }
    ///重载 除法运算符
    Biginteger operator / (const Biginteger &m) const
    {
        if (m == Biginteger()) return m;
        Biginteger res(sign ^ m.sign, div(num, m.num));
        if (res.sign && res.num.size() ==  && res.num[] == )
            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-]);
        for(int i=size-; i>=; i--)
            printf("%08d",num[i]);
        puts("");
    }
};

Biginteger f[N+];
char s[N];
void init()
{
    f[]=,f[]=f[]=;
    for(int i=;i<=N;i++) f[i]=f[i-]+f[i-];
}
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=,ub=N;
        while(lb<ub)
        {
            mid=(lb+ub)>>;
            if(f[mid]>buf+) ub=mid;
            else lb=mid+;
        }
        ((buf-f[lb-])%MOD).out();
    }
    return ;
}