版权声明:原来这里可以拿来卖萌ヽ(・∀・)ノ https://blog.csdn.net/u012345506/article/details/81453527
首先要弄清楚一个东西:B所下的结论是在“C不知道B的结论”的条件下给出的,否则题目就是矛盾的。
先考虑C如何在只知道
的情况下确定
,显然此时唯一的方法就是枚举所有的
,如果
的值都相等,那么即可确定结果。而通过简单的计算:
可以知道,给定的
中,每一组
的值必然互不相同,即当且仅当
即
是一个素数时,C才可以直接确定
。
那么,如果B能够得出结论”C不可能直接确定 “,则表示所有的 ,而显然的, 是不能满足的,其余情况都能满足。
最后,当C得到B的结论后,能够确定结果当且仅当只有唯一的一组 ,注意到这组数必然为 (因为 不能为素数),故我们得到了结论:一个 满足条件,当且仅当 ,同时对 ,都有 。
故我们枚举 的因数直接计算即可,时间复杂度 。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
//Container--
//
#define clr(a) memset(a,0,sizeof(a))
typedef long long ll;const int up=5e6;
int ds[up+10],pn,pr[up+10];bool bd[up+10];ll sm[up+10];
void _init(){
int i,j,d,k,t;for(pn=0,i=2;i<=up;++i){
if(!bd[i])pr[pn++]=i;
for(j=0;j<pn&&(ll)pr[j]*i<=up;++j){
bd[pr[j]*i]=1;
if(!(i%pr[j]))break;
}
}
for(i=3;i<=up;ds[i++]=1);
for(i=2;i<=up;++i)for(j=i+i;j<=up;j+=i){
if(bd[i+j/i-1])ds[j]=0;
}
for(i=3;i<=up;++i)if(!bd[i])ds[i]=0;
for(i=3;i<=up;++i)sm[i]=ds[i-1]?i:0;
for(i=3;i<=up;++i)sm[i]+=sm[i-1];
};
void cl(){
int i,j;scanf("%d %d",&i,&j);printf("%lld\n",sm[j]-sm[i-1]);
};
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;scanf("%d",&t);for(_init();t--;cl());
return 0;
};