首页 > 其他分享 >质数差列 题解

质数差列 题解

时间:2024-07-30 16:19:14浏览次数:8  
标签:log 题解 质数 差列 ll 欧拉 define

题目id:20315

题目描述

驰骋宇宙的鱼大大找到了一个古遗迹,稍作研究后发现这是一个来着远古的质数星球文明遗迹,这个文明的特点是所有事物都和质数息息相关。于是,鱼大大赶紧列出了一堆的质数,以方便自己的研究。
这天鱼大大找到了质数星球文明的一个遗迹仓库大门,正准备破解密码的同时,助手羊大大找到了一段提示:此仓库密码为质数差列的和。
好在经过一段时间的研究鱼大大已经知道了质数差列为何物:已知长度为n的质数数列。对于一个长度为\(n\)的质数差列,其第一项\(a_1\)为第n个质数,之后的每一项\(a_i\)与前一项\(a_{i-1}\)的差为质数数列中的倒数第\(i\)项。
现给出质数差列的长度,问最后破解的密码为何?(即质数差列的和)

解题思路

由于题目中其第一项\(a_1\)为第n个质数这一句,再结合\(n\leq 10000\)的条件,枚举显然会浪费很多时间。
所以,我们考虑使用素数筛算法解决此题。
目前三种主流的筛法都可以通过本题:\(O(n\sqrt{n})\)的朴素筛、\(O(n\log\log n)\)埃拉托色尼筛法以及\(O(n)\)的欧拉筛(又称线性筛)
虽然都可通过,但我还是推荐大家使用欧拉筛(因为快)

欧拉筛的原理:

我们从\(2\)开始,逐条对\(2\sim 104729\)进行遍历(\(104729\)为第\(10000\)个质数)。
假设我们当前遍历到的数为\(i\),如果发现\(i\pmod x=0(x\)为枚举的质数\()\),则我们把\(i\)标记为非质数,因为\(i\)可以表示成至少两个数的乘积,这不符合质数的定义(在大于\(1\)的自然数中,除了\(1\)和该数自身外,无法被其他自然数整除的数)
到这里,大家觉得可能与\(O(n\log\log n)\)的埃拉托色尼筛法差不多,但欧拉筛的时间复杂度为\(O(n)\),显然还要做进一步优化。
我们知道,\(12\)可以表示成\(2×6\)或\(3×4\),这就导致了\(12\)既会被\(2\)筛掉一遍,又会被\(3\)筛掉一遍,十分浪费时间。
那我们如何避免这个问题呢?
我们只需要在代码里加上这一句即可:
if(i%prime[j]==0)break;
其中prime[j]为第\(j\)个质数。
这样就可以保证每个数只被筛掉1遍
欧拉筛代码如下:

for(ll i=2;i<104730;++i)
{
    if(!isprime[i])prime[++cnt]=i;
    for(ll j=1;j<=cnt&&prime[j]*i<104730;++j)
    {
        isprime[prime[j]*i]=1;
        if(i%prime[j]==0)break;
    }
}

后面的求和大家都会吧,不在此过多赘述了。

AC Code

#include<bits/stdc++.h>
#define N 1000007
#define INF 2147483647
#define ll long long
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define IOS ios::sync_with_stdio(0),cin.tie(nullptr),cout.tie(nullptr)
std::mt19937_64 rnd(time(nullptr));
using namespace std;
ll n,ip[N+5],p[N+5],cnt,sum,a;
int main()
{
    IOS,cin>>n;
    for(ll i=2;i<=N;++i)
    {
        if(!ip[i])p[++cnt]=i;
        for(ll j=1;j<=cnt&&p[j]*i<=N;++j)
        {
            ip[p[j]*i]=1;
            if(i%p[j]==0)break;
        }
    }
    for(int i=n;i;--i)a+=p[i],sum+=a;
    cout<<sum;
    return 0;
}

标签:log,题解,质数,差列,ll,欧拉,define
From: https://www.cnblogs.com/988176-/p/18332705

相关文章

  • [POI2008] POC-Trains 题解
    前言题目链接:洛谷。时间复杂度和输入同阶的做法。题意简述有\(n\)(\(n\leq10^3\))个长\(m\)的字符串,\(q\)(\(q\leq10^5\))次操作,交换两个字符串的两个字符。问每个字符串在所有时刻,最多有几个和它相等。题目分析套路做法看到字符串相等,想到使用哈希。但是要支持修改,怎么......
  • 题解:[ABC363D] Palindromic Number
    提示特定位数的回文数数量是可以快速计算出来的,对于特定的位数\(n\),第一位由于不能有前导\(0\),共有\(9\)种选择,而从第\(2\)位到第\(\frac{n+1}{2}\)位都有\(10\)种选择(一个回文数完全由它的前半部分确定)。所以\(n\)位数中共有\(S(n)=9*10^\frac{n-1}{2}......
  • P3811 【模板】模意义下的乘法逆元 题解
    【模板】模意义下的乘法逆元题目背景这是一道模板题题目描述给定n,pn,pn,p求......
  • 题解:Codeforces Round 962 (Div. 3) D
    D.Funtimelimitpertest:2secondsmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputCountingisFun!—satyam343Giventwointegers\(n\)and\(x\),findthenumberoftriplets(\(a,b,c\))ofpositiveintegerss......
  • [USACO1.5] 八皇后 Checker Challenge 题解
    [USACO1.5]八皇后CheckerChallenge题目描述一个如下的\(6\times6\)的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。上面的布局可以用序列\(2\4\6\1\3\5\)来描述,第\(i\)个数字表示在......
  • 题解:P10815 【模板】快速读入
    闲着没事儿水篇tj题目大意题目大意极其粗暴,记得\(10^8\times10^8=10^{16}>2^{31}-1\)会爆int,开longlong就好。于是这个题就变成了一个读入输出优化模板题。这不又回去了。另外,输入输出常数优化也很常用,抢最优解和骗分时都可以用上。1cin/cout版本操作ios::......
  • 奇怪的汉诺塔 - 题解
    奇怪的汉诺塔时间限制:C/C++1000MS,其他语言2000MS内存限制:C/C++256MB,其他语言512MB描述汉诺塔问题,条件如下:这里有\(A\)、\(B\)、\(C\)和\(D\)四座塔。这里有\(n\)个圆盘,\(n\)的数量是恒定的。每个圆盘的尺寸都不相同。所有的圆盘在开始时都堆叠在塔\(A\)......
  • 昆虫繁殖 - 题解
    昆虫繁殖时间限制:C/C++1000MS,其他语言2000MS内存限制:C/C++256MB,其他语言512MB描述科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强。每对成虫过\(x\)个月产\(y\)对卵,每对卵要过两个月长成成虫。假设每个成虫不死,第一个月只有一对成虫,且卵长成成虫后......
  • 【入门】汉诺塔的移动次数 - 题解
    【入门】汉诺塔的移动次数时间限制:C/C++1000MS,其他语言2000MS内存限制:C/C++128MB,其他语言256MB描述汉诺塔的问题大家都已经很熟悉了,有三个柱子,每个柱子上有一些大小不一的金片,要把金片从\(A\)柱移动到\(C\)柱,可以借助\(B\)柱,请问\(n\)个金片的情况下,需要最少移......
  • 【基础】递归问题—汉诺塔 - 题解
    【基础】递归问题—汉诺塔时间限制:C/C++1000MS,其他语言2000MS内存限制:C/C++127MB,其他语言254MB描述汉诺塔(又称河内塔)问题是印度的一个古老的传说。开天辟地的神勃拉玛在一个庙里留下了三根金刚石的棒,第一根上面套着\(64\)个圆的金片,最大的一个在底下,其余一个比一个小......