您的位置:首页 > 其它

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

2018-02-10 19:49 501 查看
题意: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 <
4000
span class="hljs-keyword">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
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息