神犇请进!!!81分求助!!!

P1865 A % B Problem

...
by MuYC @ 2019-07-18 08:48:31


要预处理
by royzhu @ 2019-07-18 08:48:50


首先 这道题目我们乍一看,黄题,好像不简单, 其实是我太水了 但是,分析后,你就会发现这道题的简单了。 思路: 看数据范围:m<=1000000,这样的话,如果你暴力,绝对会超时,所以,我们有好办法:先求出m内的所有素数,然后,我们就只要判断prime[i]<=R&&prime>=L就行了,这样的话,时间复杂度就会大大降低,我的总用时为:2651ms,虽然不是很快,但是跑起来不超时也是绰绰有余的。 关于如何筛选素数: 这道题的m范围不大,我们采用线性筛素数法,什么?不知道什么是线性筛素数法? 我来给你先科普下吧。 线性筛素数法:又叫埃拉托斯特尼筛法 先简单说一下原理: 基本思想:素数的倍数一定不是素数 实现方法:用一个长度为N+1的数组保存信息(0表示素数,1表示非素数),先假设所有的数都是素数(初始化为0),从第一个素数2开始,把2的倍数都标记为非素数(置为1),一直到大于N;然后进行下一趟,找到2后面的下一个素数3,进行同样的处理,直到最后,数组中依然为0的数即为素数。 说明:整数1特殊处理即可。 举个例子,N=20时,演示如下图: 我们找到一个素数后,把它m范围内的倍数全部标记,便于查找(一个素数的倍数一定是合数,小学生都知道的道理) OK,要讲的都讲完了,下面贴代码: ```cpp #include <bits/stdc++.h> int prime[1000005]={0},t=0,m; bool book[1000005]; using namespace std; int check(int x){//线性筛素数模板 for(int i = 2;i <=sqrt(x);i++) if(x%i==0)return 0; t++; prime[t]=x;//x进入素数列 for(int i = x+x;i <= m;i += x) book[i]=1;//标记x的倍数 } int main(){ int i,j,k,n,L,R,total; cin>>n>>m; for(i = 2;i <= m;i++){ if(book[i]!=1) check(i);//如果i没有被标记过,就判断i是否为素数 } for(i = 1;i <= n;i++){ cin>>L>>R;//判断R、L是否满足条件 if(R>m||L<=0||R<L)printf("Crossing the line\n"); else { total=0; for(j=1;j<=t;j++){//判断prime[j]是否满足条件 if(prime[j]>=L&&prime[j]<=R)total++; else if(prime[j]>R)break;//当prime[j]>R,再往后也没意义了,退出循环。 } printf("%d\n",total); } } return 0; } ``` 我没成功审核通过的题解+1
by MuYC @ 2019-07-18 08:50:01


O(N^2\*sqrt(N))的时间复杂度显然过不了某些点 试试欧拉筛(线性筛)吧
by theaceblock @ 2019-07-18 08:50:48


楼上就是埃筛
by MuYC @ 2019-07-18 08:51:29


欧拉函数更强Orz
by MuYC @ 2019-07-18 08:52:05


![](https://cdn.luogu.com.cn/upload/pic/64322.png ) # 谢谢各位大佬,我AC了
by judgejudge @ 2019-07-18 08:54:07


时间复杂度低。。好低/
by MuYC @ 2019-07-18 08:56:15


@[Aloor°川北](/space/show?uid=67817) 线筛和埃筛不一样吧
by Celestial_Scarlet @ 2019-07-18 08:57:00


@[Aloor°川北](/space/show?uid=67817) 不打同步赛了吗?
by Vanity_ @ 2019-07-18 09:00:49


| 下一页