第1個質數是2,第3個質數是5,給出乙個數n,求第n個質數。
很明顯這個要二分答案。
現在的主要問題就是求f[i]表示i裡面有多少個質數。
這裡可以用個非正式的洲閣篩。 設 f
[i]表
示i以內
有多少個
質數 p
[i]表
示第i個
質數 g
[i][
j]表示
前i個數
不被p[
1...j]
整除的數
有多少個
那麼先來看看f,首先我們知道乙個數i可以被i√
以內的質數給篩掉,那麼篩不掉的就是質數,所以有f[
i]=f
[i√]
+g[i
][f[
i√]]
-1,因為1不是質數。
然後p可以用線篩來解決。
g[i][j]可以從g[i][j-1]推過來,但是g[i][j-1]還包括一些是p[j]的倍數的數:p[
j],2
p[j]
,3p[
j],4
p[j]
...i
p[j]
p[j]
,所以就要排除掉
[1...ip
[j]]
中是p[
1...j−
1]倍數
的 ,所以有g[
i][j
]=g[
i][j
−1]−
g[ip
[j]]
[j−1
] 但是只有這個還不行,時間卡不過去。
我們考慮如何在根號時間內處理好。
那麼很明顯要優化求g的時間。
所以這裡有兩個優化:
1、當f[i
]<=
j ,那麼g[i][j]=1,因為j包含了組成[2…i]的所有質數,那麼除了1以外,其他的數都會被整數。
2、如果不滿足上面的條件,當f[
i√]<=
j ,那麼g[i][j]=f[i]+1-j,因為[1…i]的數可以由i√
裡所有的質數給篩掉,但是j包含了這些質數,那麼只有除了這j個質數之外的質數,和1可以不被整除了。
剩下的要考慮的就是空間與時間的問題,51nod這道題不打表還跑得挺慢的。
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
const
int maxn=7500000+7;
typedef
long
long ll;
using
namespace
std;
ll i,j,k,t,n,m,ans;
ll r,mid,l;
int f[maxn],p[maxn];
bool bz[maxn];
ll g(ll n,int m)
return g(n,m-1)-g(n/p[m],m-1);
}bool pan(ll x)
int main()
}fo(i,2,maxn-7)f[i]=f[i-1]+(bz[i]==0);
scanf("%d",&n);
l=1,r=22801763489;
while(l2;
if(pan(mid))r=mid;else l=mid+1;
}printf("%lld\n",l);
}
51nod 2141 第N個智慧型數
題目 乙個正整數如果能表示成兩個正整數的平方差,則稱這個數為乙個 智慧型數 比如 16 就等於 5的平方減去 3 的平方,所以 16 就是乙個智慧型數,從 1 開始的自然數列中,將 智慧型數 從小到大編號為 1,2,3,n。現輸入乙個正整數 n,輸出第 n 個 智慧型數 輸入輸入僅包含乙個正整數 n...
51nod 1126 求遞推序列的第N項
1126 求遞推序列的第n項 基準時間限制 1 秒 空間限制 131072 kb 分值 10 難度 2級演算法題 有乙個序列是這樣定義的 f 1 1,f 2 1,f n a f n 1 b f n 2 mod 7.給出a,b和n,求f n 的值。input 輸入3個數 a,b,n。數字之間用空格分割...
51Nod 1126 求遞推序列的第N項
include include define maxn 3 define mod 7 using namespace std typedef long long ll int n ll b n 0,c maxn h maxn struct matrix matrix multi matrix a,m...