1. 程式人生 > >[51nod1333][亂搞]無聊的數學家們

[51nod1333][亂搞]無聊的數學家們

Description

問題來自於一個精彩的故事:
有三個數學家,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)。

Input

多組測試資料,第一行一個整數T,表示資料個數,其中1<=T<=10.
之後有T行,每行兩個數L與R,表示一組詢問,其中1<=L<=R<=5,000,000.

Output

輸出T行,每行一個整數,即[L,R]區間中所有符合條件的S的和。

Sample Input

3
30 33
8 11
40 43

Sample Output

33
19
0

題解

這題很有意思啊
首先考慮BB怎麼確定CC是不能100100%知道的,顯然是BB的數不是質數+1
因為如果CC的數是個質數,他只有一種分解方式…
然後我們再來觀察C是怎麼確定的
CC的數是TT
T

T的某種拆分方式是xyx*y
顯然是隻有一種拆分使得x+y1x+y-1不是質數
知道TT是個合數
可以知道1T1*T這組拆分是合法的,因為1+T1+T顯然不是質數+1
這樣我們只需要知道一個數的某個拆分不是質數就可以知道他不合法
列舉約數,這個可以調和級數NlogNNlogN把不合法的篩出來
然後就做完了…

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include
<queue>
#include<vector> #include<ctime> #include<map> #include<bitset> #define LL long long #define mp(x,y) make_pair(x,y) using namespace std; inline int read() { int f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void write(LL x) { if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); } inline void pr1(int x){write(x);printf(" ");} inline void pr2(LL x){write(x);puts("");} bool v[5000005];int pr[5000005],plen; void getpr() { memset(v,true,sizeof(v));v[1]=false; for(int i=2;i<=5000000;i++) { if(v[i])pr[++plen]=i; for(int j=1;j<=plen&&i*pr[j]<=5000000;j++) { v[i*pr[j]]=false; if(!(i%pr[j]))break; } } } LL sum[5000005]; int main() { getpr(); for(int i=1;i<=5000000;i++)sum[i]=i; for(int i=2;i<5000000;i++) for(int j=i;(LL)i*j<=5000000;j++) if(!v[i+j-1])sum[i*j+1]=0; for(int i=1;i<=5000000;i++)if(v[i])sum[i+1]=0; sum[1]=sum[2]=0; for(int i=1;i<=5000000;i++)sum[i]=sum[i-1]+sum[i]; int T=read();while(T--) { int l=read(),r=read(); pr2(sum[r]-sum[l-1]); } return 0; }