提问者:小点点

值域上的素数对和复合对


你得找到不。 关于在给定范围内选择一对素数(p)和一个复合数(q)的方法。 L<=P,Q<=R输入:-

第一行包含整数T,否。 测试用例。

接下来的T行包含两个空间整数l和R。

输出:-

每个测试用例都有一个输出,no。 素数对和一个复合数在新的行中。

约束1<=T<=10^5 1<=L,R&<=10^5

我已经写了一个代码使用筛选算法,但它不工作在一些情况下。。。(例如情况1到100000)和一些它显示超时。

#include <iostream>
using namespace std;

int* sievealgo(){

    int* A=new int[100005];
    A[0]=A[1]=1;
    for(long long i=2;i*i<=100004;i++){

        if(A[i]==0){
            for(int j=i*i;j<=100004;j+=i){
                A[j]=1;
            }
        }

    }
    return A;
}

int main() {

    int n,x,l,r;
    int *A;
    cin>>n;
    A=sievealgo();

    for(int i=0;i<n;i++){
        int count=0;
        cin>>l;
        cin>>r;
        for(int i=l;i<=r;i++){
            if(A[i]==0) count++;
        }
        cout<<(r-l+1-count)*count<<endl;
    }

}

共1个答案

匿名用户

您的程序太慢,因为您使用的是嵌套循环。 当输入为

100000
1 100000
(99999 more "1 100000" lines)

您的程序将需要大约10^10个步骤,对于在当今计算机上运行的非并行程序来说太大了。

而不是那样,你应该

1.分配另一个数组(例如count)

2.使数组保存0到索引(含)的素数

index:  0  1  2  3  4  5  6  7  8  9  ...
A    :  1  1  0  0  1  0  1  0  1  1  ...
count:  0  0  1  2  2  3  3  4  4  4  ...

你可以通过

  1. 正在将计数[0]初始化为0
  2. 对于具有正索引i的每个元素,如果a[i]!=0(非素数),则将count[i]设置为count[i-1],如果a[i]==0(素数),则将count[i-1]+1设置为count[i-1]+1

3.现在Lr(包括两个)之间的素数个数为Count[r]-Count[l-1]

另外,正如@igortandetnik所指出的,

int* A=new int[100005];

不要对元素进行初始化,所以应该在筛选之前手动给每个元素赋0。

引自N3337:

5.3.4新增15

如果省略new-initializer,则对象默认初始化(8.5); 如果不执行初始化,则对象的值不确定。

8.5初始值设定项6

默认初始化T类型的对象意味着:

  • 如果T是(可能是CV限定的)类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式不正确);
  • 如果T是数组类型,则每个元素都是默认初始化的;
  • 否则,不执行初始化。

现在int既不是类,也不是数组,不执行初始化,并且值不确定。