首页 > 其他分享 >洛谷题单指南-模拟和高精度-P1045 [NOIP2003 普及组] 麦森数

洛谷题单指南-模拟和高精度-P1045 [NOIP2003 普及组] 麦森数

时间:2024-01-25 18:22:07浏览次数:29  
标签:2p 麦森数 NOIP2003 int 洛谷题 高精度 result 500 位数

原题链接:https://www.luogu.com.cn/problem/P1045

题意解读:

要计算2p- 1的位数和最后500位,实际上只需要计算2p,两者位数一致,前者比后者个位减1即可,且个位肯定不会是0,比较容易处理。

解题思路:

如果直接采用高精度乘法计算2p,p最大3.1*106, 高精度所用数组最长大概9*105,一共最多计算3.1*106*9*105,超时,需要考虑优化。

1、对于位数的计算

我们知道,一个十进制数的位数很好计算,假设一个十进制数为10k,则位数为k+1;

那么,如果2p能转化为10k形式,问题就得以解决;

因为2 = 10log102,所以2p = (10log102)p = 10log102 * p

进而可得到位数:log102 * p + 1,取整。

log10()为系统函数。

2、对于后500位的计算

由于数据位数可高达9*105位,如果保存完整的数据进行高精度乘法,势必超时

但题目要求只取后500位,相当于结果取模10500

因此,乘法结果取模,相当于对乘法的每个因子取模后再相乘

这样,在高精度乘法的时候,每次只用保留最低500位即可,其余高位的数据可以舍弃不必计算

另外,如果每次都乘以2,一共最大要乘3.1*106次,每次高精度取500位,最大复杂度大概3.1*106*500,同样会超时

而如果每次都乘以230,则最多乘的次数大概100000次,每次高精度取500为,复杂度估算在5 * 107

所以,需要先设n = p / 30,则有n个230相乘,再看m = p % 30,结果还要乘上2m

为了减少计算时间,可以提前预处理出21、22、23...230的结果

注意为什么不取到231?因为int最大是231-1 

100分代码:

#include <bits/stdc++.h>
using namespace std;

int pow2[31];

//初始化2的1、2...30次方
void init()
{
    int ans = 1;
    for(int i = 1; i <= 30; i++)
    {
        ans *= 2;
        pow2[i] = ans;
    }
}

//高精度*低精度,每次只取前500位,即模10^500,起到优化时间复杂度的效果
vector<int> mul(vector<int> &a, int b)
{
    vector<int> result;
    long long t = 0;
    for(int i = 0; i < a.size() && result.size() < 500; i++)
    {
        t += (long long)a[i] * b;
        result.push_back(t % 10);
        t /= 10;
    }
    while(t && result.size() < 500)
    {
        result.push_back(t % 10);
        t /= 10;
    }

    return result;
}

int main()
{
    init();
    int p;
    cin >> p;

    cout << (int)(log10(2) * p + 1) << endl; 

    int n = p / 30; //p有多少个30,要计算n次2^30相乘
    int m = p % 30; //如果m不为0,计算n次2^30相乘后,再乘以2^m

    vector<int> ans(1, 1);
    for(int i = 1; i <= n; i++) ans = mul(ans, pow2[30]); //计算n次2^30相乘
    ans = mul(ans, pow2[m]); //再乘以2^m

    ans[0] -= 1; //个位减1

    while(ans.size() < 500) ans.push_back(0); //不足500位,高位补0

    for(int i = ans.size() - 1, j = 1; i >= 0; i--, j++)
    {
        cout << ans[i];
        if(j % 50 == 0) cout << endl;
    }

    return 0;
}

 

标签:2p,麦森数,NOIP2003,int,洛谷题,高精度,result,500,位数
From: https://www.cnblogs.com/jcwy/p/17987865

相关文章

  • 洛谷题单指南-模拟和高精度-P1249 最大乘积
    原题链接:https://www.luogu.com.cn/problem/P1249题意解读:题目分两步,第一步是将整数拆分成不同自然数的和,第二步通过高精度计算这些因数的乘积,要使乘积最大,需要某种贪心思想。解题思路:如何保证整数拆分后因子的乘积最大呢,有几个原则:1、最好不要包括因子1,但3、4除外,需要进行特......
  • 洛谷题单指南-模拟和高精度-P1591 阶乘数码
    原题链接:https://www.luogu.com.cn/problem/P1591题意解读:此题核心就是通过高精度*低精度计算阶乘,然后统计数码个数即可,直接给出代码。100分代码:#include<bits/stdc++.h>usingnamespacestd;vector<int>mul(vector<int>&a,intb){vector<int>result;intt......
  • 洛谷题单指南-模拟和高精度-P1786 帮贡排序
    原题链接:https://www.luogu.com.cn/problem/P1786题意解读:此题比较简单,模拟+排序即可解决。需要注意的是,当帮贡或者等级相同时,都要保持原来的顺序,因此需要记录每个人的编号,便于排序。话不多说,直接上代码。100分代码:#include<bits/stdc++.h>usingnamespacestd;constint......
  • Luogu P1042 [NOIP2003 普及组] 乒乓球
    [NOIP2003普及组]乒乓球\(link\)题目背景国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。其中\(11\)分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役。华华就是其中一位,他退役之后走上了乒乓球研究工作,意图......
  • 洛谷题单指南-模拟和高精度-P1098 [NOIP2007 提高组] 字符串的展开
    原题链接:https://www.luogu.com.cn/problem/P1098题意解读:题目本身是一道模拟题,但是细节点较多,要拿100分,有以下注意点:1、-号两个需要同时为小写字母或者数字,才进行填充2、-号左边>=右边,直接输出-3、对待填充的内容的处理,可以先看是否填充*;小写字母和数字的填充都是前一位asci......
  • 洛谷题单指南-模拟和高精度-P1067 [NOIP2009 普及组] 多项式输出
    原题链接:https://www.luogu.com.cn/problem/P1067题意解读:模拟法依次输出多项式内容即可,但是需要考虑的周全,主要有以下关键点:1、系数为0时不输出多项式2、第一个符号,只有负号才输出3、次数不为0时,不输出为1的系数;次数为0时,输出所有系数4、次数为1时,不输出次数;次数为0时不输......
  • 洛谷题单指南-模拟和高精度-P1518 [USACO2.4] 两只塔姆沃斯牛 The Tamworth Two
    原题链接:https://www.luogu.com.cn/problem/solution/P1518题意解读:此题是一道模拟题,关键要解决几个问题:1、如何转换方向2、如何在地图中移动3、如何判断无法抓住牛。解题思路:定义chara[10][10]用于存储地图,cx,cy和fx,fy分别代表牛、Farmer所在的位置,cdir、fdir分别代表牛......
  • 洛谷题单指南-模拟和高精度-P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布
    原题链接:https://www.luogu.com.cn/problem/P1328题意解读:非常简单的一道题,核心考点就是循环数组以及评分规则的构建。评分规则:甲vs乙,1表示甲赢,-1表示甲输,-0表示平转化为数组:intrule[5][5]={0,-1,1,1,-1,1,0,-1,1,-1,-1,1,0,-1,1,-1,......
  • 洛谷题单指南-模拟和高精度-P4924 [1007] 魔法少女小Scarlet
    原题链接:https://www.luogu.com.cn/problem/P4924题意解读:根据题意,通过模拟法,枚举每一个要旋转的矩阵,执行旋转操作即可,关键点在于如何进行矩阵旋转。设定矩阵inta[][],临时矩阵intt[][]用于保存旋转后的矩阵,矩阵长度为len。先考虑要旋转的区域左上角是a[0][0]的情况,区域内每......
  • 洛谷题单指南-模拟和高精度-P1601 A+B Problem
    原题链接:https://www.luogu.com.cn/problem/P1601题意解读:本题是高精度加法的模版题。知识点解析:  高精度加法:  如果一个数大到远超过整形变量的范围时,就不能使用int、long、longlong等变量来存储整数,也不能直接通过变量加法来求和。  因此,需要回到加法计算的本质,从个......