zoukankan      html  css  js  c++  java
  • 牛客挑战赛53 B.简单的序列(bitset,哥德巴赫猜想)

    传送门


    解题思路

    和洛谷 P3674 很像。首先对于质数输出其本身。然后对于合数,根据哥德巴赫猜想,偶数一定可以由两个质数相加得到,而奇数则可以由两个或者三个质数得到。

    但是三个数的和不好找,于是可以把奇数-1得到偶数进行求解。

    然后就可以预处理1~1e7的质数,扔到bitset里,每次询问相当于询问是否有两个数相加的和为s。

    总复杂度\(O(\frac{TS}{w})\)

    但评测机波动赛时两发没过赛后一发就过了就离大谱了。。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e7;
    int T,s,prime[maxn/10+5],cnt;
    bitset<10000005> a,b,c;
    bool vis[maxn+5];
    int main(){
    	ios::sync_with_stdio(false);
    	a[1]=b[maxn-1]=1;
    	for(int i=2;i<=maxn;i++){
    		if(!vis[i]) prime[++cnt]=i;
    		for(int j=1;j<=cnt&&i*prime[j]<=maxn;j++){
    			vis[i*prime[j]]=1;
    			if(i%prime[j]==0) break;
    		}
    	}
    	for(int i=1;i<=cnt;i++) a[prime[i]]=b[maxn-prime[i]]=1;
    	cin>>T;
    	while(T--){
    		cin>>s;
    		if(vis[s]==0){
    			cout<<1<<endl<<s<<" = "<<s<<endl;
    			continue;
    		}
    		if(s==0){
    			cout<<1<<endl<<"0 = 0"<<endl;
    			continue;
    		}
    		c=b&(a<<(maxn-s));
    		if(c.any()){
    			int x=maxn-c._Find_first();
    			cout<<2<<endl<<x<<" + "<<s-x<<" = "<<s<<endl;
    			continue; 
    		}else{
    			s--;
    			c=b&(a<<(maxn-s));
    			int x=maxn-c._Find_first();
    			cout<<3<<endl<<"1 + "<<x<<" + "<<s-x<<" = "<<s+1<<endl;
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    输入输出,数据类型,运算符
    queue与pair
    迪杰斯特拉算法学习
    IP地址/数字表示学习
    作业与进程的关系
    直写和回写学习
    OS中的时空局部性
    scanpy包的预处理函数学习
    keras编译与训练过程
    力扣:前缀和、差分题目
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15413380.html
Copyright © 2011-2022 走看看