51Nod1333--无聊的数学家们
Posted ihopenot
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51Nod1333--无聊的数学家们相关的知识,希望对你有一定的参考价值。
题意 : (蛮有意思的一个小故事) 有三个数学家,A,B与C。A选了两个正整数x与y满足x<=y。然后,A将x+y的值告诉了B,A又将x*y的值告诉了C。B与C都不知道x与y分别是什么,也不知道对方得到的值是什么。但B和C知道A告诉B的值是某两个正整数的“和”而告诉C的值是这两个数的“积”。而且这三个数学家的数学功底足够好。下面是B与C进行的对话:
B:“我确定你一定没有百分百的把握猜中我得到的数。”
C:“谢谢你的提示。现在我能确定你获得的数是 S。”
故事结束,回到问题。
这个故事中一共涉及3个未知参数x,y与S,其实由于S=x+y,所以实际一共只有两个未知参数而已。你可以带入一些正整数让这个故事没有逻辑漏洞。现在问题来了,在区间[L,R]上存在多少个数值t,使S=t时能找到对应的x与y,并让这个故事成立。输出这些t的和(1<=L<=R<=5,000,000)。
------------------------------------------------------------此后一千里------------------------------------------------------------------
稍微想了一下,发现有几个关键点。
一是如果C能百分百确定x和y,那么x*y一定是个质数,即xy中一个为1,一个为质数
然后反推出x+y-1不是个质数,因为B肯定C不能百分百确定
二是C根据B的言语知道x+y-1不是个质数就能推出自己的数,那说明所有x*y=a*b里面,只有一组ab不满足a+b-1是质数
然后发现x*y总能拆成1*x*y,而根据上面的推理,x*y不是个质数,所以唯一拆分即为x*y,1,所以其他拆分如果不满足a+b-1是个质数,那么这个S就不可行
然后每个S可行与否可以去筛出来
代码 :
#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define low(x) ((x)&(-(x))) #define LL long long #define eps 1e-9 using namespace std; #define int int inline int Max(int a,int b) {return a>b?a:b;} inline int Min(int a,int b) {return a<b?a:b;} inline int Abs(int a) {return a>0?a:-a;} inline int Sqr(int a) {return a*a;} #undef int #define MAXN 5000005 LL pre[MAXN];bool ok[MAXN]; bool mk[MAXN];int pri[MAXN],cnt,n; void Pre(int n) { for(int i=2;i<=n;i++) { ok[i]=1; if(!mk[i]) pri[++cnt]=i; for(int j=1;j<=cnt&&i*pri[j]<=n;j++) { mk[i*pri[j]]=1; if(i%pri[j]==0) break; } } for(int i=2;i<=n;i++) for(int j=i+i;j<=n;j+=i) ok[j]&=!mk[i+j/i-1]; for(int i=2;i<=n;i++) pre[i]=pre[i-1]+(ok[i-1]&&mk[i-1]?i:0); } int main() { int T,l,r;cin>>T; Pre(5000000); while(T--) { scanf("%d%d",&l,&r); printf("%lld\\n",pre[r]-pre[l-1]); } return 0; }
以上是关于51Nod1333--无聊的数学家们的主要内容,如果未能解决你的问题,请参考以下文章