zoukankan      html  css  js  c++  java
  • [HAOI2007][SDOI2005]反素数

    题目:洛谷P1463、BZOJ1053、Vijos P1172、codevs2912。

    题目大意:对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。

    如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。

    现在给定一个数N(≤2,000,000,000),求出不超过N的最大的反质数。

    解题思路:N那么大,第一反应是找规律。

    首先得打出一个范围较小的表(三秒内能打完的),发现:范围大,但反素数很少。

    于是果断选择了打表大法!

    不过打表也得讲究技巧。首先发现所有反素数(除1以外)都是偶数,那么在循环判断时只需循环偶数即可。

    其次发现从60开始,每个反素数都是20的倍数,那么此时每次加20即可。

    但二十亿个数,还是很多。怎么办?我们发现,两个反素数直接总是相差很多,那我们每求出一个反素数,就跳过一部分,使得减少循环次数。

    最终,成功打出表,见代码(最后那个$2^{32}-1$是占位用的)。

    C++ Code:

    #include<cstdio>
    const int a[]={1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,
    5040,7560,10080,15120,20160,25200,27720,45360,50400,55440,83160,110880,166320,
    221760,277200,332640,498960,554400,665280,720720,1081080,1441440,2162160,2882880,
    3603600,4324320,6486480,7207200,8648640,10810800,14414400,18378360,21621600,32432400,
    36756720,43243200,61261200,73513440,110270160,122522400,147026880,183783600,245044800,
    328648320,410810400,551350800,698377680,735134400,1102701600,1396755360,2147483647};
    int main(){
    	int n;
    	scanf("%d",&n);
    	for(int i=0;;++i)
    	if(a[i]>n){
    		printf("%d
    ",a[i-1]);
    		return 0;
    	}
    }
    

    下附打表代码,在我家里的渣机上跑了33分02秒279(O2优化下),不过总归是能打完的。

    #include<cstdio>
    #define reg register
    #define ull unsigned long long
    int main(){
    	freopen("output.txt","w",stdout);
    	printf("1,");
    	reg int t=2;
    	reg ull max=1;
    	for(reg ull i=2;i<=2000000200;i+=t){
    		if(i==60)t=20;
    		reg ull p=1,k=i;
    		for(reg int j=2;j*j<=k;++j)
    		if(k%j==0){
    			reg ull f=1;
    			for(;k%j==0;k/=j,++f);
    			p*=f;
    		}
    		if(k>1)p<<=1;
    		if(p>max){
    			max=p;
    			printf("%llu,",i);
    			if(i>=800000000)i+=100000000;else
    			if(i>=410810400)i+=30000000;else
    			if(i==328648320)i=410810380;else
    			if(i>=200000000)i+=50000000;else
    			if(i==147026880)i+=35000000;else
    			if(i>=122522400)i+=20000000;else
    			if(i>=43243200)i+=10000000;else
    			if(i>=21621600)i+=4000000;else
    			if(i>=10000000)i+=3000000;else
    			if(i>=1400000)i+=600000;else
    			if(i>=1000000)i+=300000;else
    			if(i>=100000)i+=50000;
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    四层、七层负载均衡的区别
    confd+etcd实现高可用自动发现
    从零开始搭建etcd分布式存储系统+web管理界面
    从零开始搭建Prometheus自动监控报警系统
    tcpdump工具使用说明
    Nginx的负载均衡
    Nginx的正向代理与反向代理详解
    linux集群自动化搭建(生成密钥对+分发公钥+远程批量执行脚本)
    linux文件权限总结(创建root不可以删除文件、只可追加的日志文件等)
    前端技巧备忘
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7707930.html
Copyright © 2011-2022 走看看