[luoguP1045] 麦森数(快速幂 + 高精度)
这道题纯粹是考数学。编程复杂度不大(别看我写了一百多行其实有些是可以不必写的)。
计算位数不必用高精时刻存,不然可想而知时间复杂度之大。首先大家要知道一个数学公式 logn(a*b)=logn(a)+logn(b)至于证明翻数学书吧。而且,用log10(n)+1即可求出n的位数。
则2^p的位数=log10(2^p)+1=p*log10(2)+1。这样,我们算的时候就不必随时存着位数了。
但是,如果直接写高精和n次循环,时间复杂度依旧很高。所以我们就要用快速幂。幂的运算是初中内容,几个公式如下:n^a*n^b=n^(a+b),(n^a)^b=n^(a*b)。
所以,我们就可以将乘方的复杂度优化成O(logn)了。
代码
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream> using namespace std; const int MAXN = 2001; char c[MAXN]; inline char *read()
{
scanf("%s", c);
return c;
} struct Big_int
{
int s[MAXN], idx;
Big_int()
{
idx = 0;
memset(s, 0, sizeof(s));
}
inline void operator = (char *c)
{
idx = strlen(c);
for(int i = 0; i < idx; i++) s[i] = c[idx - i - 1] - '0';
}
inline void operator = (int x)
{
idx = 0;
memset(s, 0, sizeof(s));
if(!x) idx++;
while(x)
{
s[idx] = x % 10;
x /= 10;
idx++;
}
}
inline void print()
{
if(!idx) printf("0");
else for(int i = idx - 1; i >= 0; i--)
{
if(!((i + 1) % 50)) puts("");
printf("%d", s[i]);
}
puts("");
}
}; inline Big_int operator + (const Big_int x, const Big_int y)
{
Big_int ret;
ret.idx = max(x.idx, y.idx) + 1;
for(int i = 0; i < ret.idx; i++)
{
ret.s[i] += x.s[i] + y.s[i];
if(ret.s[i] >= 10)
ret.s[i + 1] += 1, ret.s[i] -= 10;
}
while(!ret.s[ret.idx - 1] && ret.idx > 1) ret.idx--;
return ret;
} inline bool operator < (const Big_int x, const Big_int y)
{
if(x.idx < y.idx) return 1;
if(x.idx > y.idx) return 0;
for(int i = x.idx - 1; i >= 0; i--)
if(x.s[i] ^ y.s[i])
return x.s[i] < y.s[i];
return 0;
} inline Big_int operator - (Big_int x, Big_int y)
{
Big_int ret;
if(x < y) swap(x, y);
ret.idx = x.idx;
for(int i = 0; i < ret.idx; i++)
{
if(x.s[i] < y.s[i])
{
x.s[i] += 10;
x.s[i + 1]--;
}
ret.s[i] = x.s[i] - y.s[i];
}
while(!ret.s[ret.idx - 1] && ret.idx > 1) ret.idx--;
return ret;
} inline Big_int operator * (const Big_int x, const Big_int y)
{
Big_int ret;
ret.idx = x.idx + y.idx;
for(int i = 0; i < x.idx; i++)
for(int j = 0; j < y.idx; j++)
{
ret.s[i + j] += x.s[i] * y.s[j];
ret.s[i + j + 1] += ret.s[i + j] / 10;
ret.s[i + j] %= 10;
}
while(!ret.s[ret.idx - 1] && ret.idx > 1) ret.idx--;
return ret;
} int p;
Big_int a, ans; int main()
{
int i, j, k, x, y;
scanf("%d", &p);
cout << floor(log(2) / log(10) * p + 1);
ans = 1;
a = 2;
while(p)
{
if(p & 1) ans = ans * a, ans.idx = min(ans.idx, 500);
a = a * a, a.idx = min(a.idx, 500);
p >>= 1;
}
a = 1;
ans = ans - a;
ans.idx = 500;
ans.print();
return 0;
}
[luoguP1045] 麦森数(快速幂 + 高精度)的更多相关文章
- 洛谷试炼场-简单数学问题-P1045 麦森数-高精度快速幂
洛谷试炼场-简单数学问题 B--P1045 麦森数 Description 形如2^P−1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果PP是个素数,2^P-1 不一定也是素数.到19 ...
- [NOIP2003普及组]麦森数(快速幂+高精度)
[NOIP2003普及组]麦森数(快速幂+高精度) Description 形如2^P-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2^P-1不一定也是素数.到1998 ...
- TZOJ 4839 麦森数(模拟快速幂)
描述 形如2^P-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2^P-1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的一个是P=3021377,它有9 ...
- 【高精度乘法】NOIP2003麦森数
题目描述 形如2^{P}-12P−1的素数称为麦森数,这时PP一定也是个素数.但反过来不一定,即如果PP是个素数,2^{P}-12P−1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的 ...
- NOIP200304麦森数
试题描述 形如2P-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2P-1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的一个是P=3021377,它有9 ...
- 【转】[NOIP2003普及组]麦森数
来源:http://vivid.name/tech/mason.html 不得不纪念一下这道题,因为我今天一整天的时间都花到这道题上了.因为这道题,我学会了快速幂,学会了高精度乘高精度,学会了静态查错 ...
- vijosP1223麦森数
vijosP1223麦森数 链接:https://vijos.org/p/1223 [思路] 快速幂+高精乘. 计算2^p-1可以快速幂的方法在O(logn)的时间内出解,限于数据范围我们需要用到高精 ...
- 洛谷 P1045 麦森数
题目描述 形如2^{P}-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2^{P}-1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的一个是P=30213 ...
- 麦森数--NOIP2003
题目描述 形如2P−12^{P}-12P−1 的素数称为麦森数,这时PPP 一定也是个素数.但反过来不一定,即如果PPP 是个素数,2P−12^{P}-12P−1 不一定也是素数.到1998年底,人们 ...
随机推荐
- leetcode 484. Find Permutation 思维题
https://leetcode.com/contest/leetcode-weekly-contest-16a/problems/find-permutation/ 设原本的数字是0,那么按照它的D ...
- 在spring data jpa中使用自定义转换器之使用枚举转换
转载请注明http://www.cnblogs.com/majianming/p/8553217.html 在项目中,经常会出现这样的情况,一个实体的字段名是枚举类型的 我们在把它存放到数据库中是需要 ...
- Zclip点击复制内容到剪贴板兼容各浏览器
WEB开发中,要让用户复制页面中的一段代码.URL地址等信息,为了避免用户拖动鼠标再进行右键复制操作而可能出现的差错,我们可以直接在页面中放置一个复制按钮,只需要轻轻一点这个复制按钮,内容将会被复制, ...
- 工作记录:JS正则表达式 angularjs ng-if ng-show ng-switch
用了一下JS 正则表达式判断密码,很简单 学习了angularjs的ng-if ng-show ng-switch的区别并使用 https://www.cnblogs.com/54td/p/59743 ...
- css3 transform + deviceorientation实现图片旋转效果
1. 陀螺仪deviceorientation的使用,参考<关于陀螺仪deviceorientation>https://segmentfault.com/a/11900000071838 ...
- java 解析四则混合运算表达式并计算结果
package ch8; import java.util.LinkedList; import java.util.List; import java.util.Stack; /** * 四则混合运 ...
- java线程池,信号量使用demo
直接上代码 package org.jimmy.threadtest20181121; import java.util.concurrent.LinkedBlockingQueue; import ...
- h5开发app,移动端 click 事件响应缓慢的解决方案
造成点击缓慢的原因 从点击屏幕上的元素到触发元素的 click 事件,移动浏览器会有大约 300 毫秒的等待时间.为什么这么设计呢? 因为它想看看你是不是要进行双击(double tap)操作. 使用 ...
- 浏览器通知Web Notifications实例页面
HTML代码: <button id="button">有人想加你为好友</button> <p id="text">< ...
- TCP的链接过程
** TCP 三次握手 四次挥手** 客户端 服务器端 交互的模式 ---> 应答模式* 应答模式 ---> 客户端发起请求 服务器端回应请求** 客户端先去发起请求 ---> 查看 ...