UVA-10539 打表+二分
阿新 • • 發佈:2018-12-19
題意非常簡單,就是給你一個區間(閉區間),然後讓你統計區間內有多少數滿足本身不是素數,但只有一個素因子
首先注意題目中區間左右端點最大可以取到1e12,這早就超越了int的表示範圍
我們首先打表計算出1e6內的素數表,然後計算所有滿足要求的數,存進陣列,最後排序
然後對於給定的區間[L,R],我們用二分找到上界和下屆
二分一直是我心中的痛,總是用不好,以後碰一道二分記錄一道
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iomanip> #include<assert.h> #include<vector> #include<list> #include<map> #include<set> #include<sstream> #include<stack> #include<queue> #include<string> #include<bitset> #include<algorithm> #pragma warning(disable:4996) #define me(s) memset(s,0,sizeof(s)) #define _for(i,a,b) for(int i=(a);i<(b);++i) #define _rep(i,a,b) for(int i=(a);i<=(b);++i) using namespace std; typedef pair <int, int> pii; typedef long long ll; typedef unsigned long long llu; const int inf = 0x3f3f3f3f; const int MOD = 1e9 + 7; const double pi = acos(-1.0); const double eps = 1e-15; const int maxn = 1000000; ll p[maxn + 5], vis[maxn + 5], pcnt; vector<ll> ans; void init() { me(vis); pcnt = 0; for (int i = 2; i<maxn; i++) { if (!vis[i]) { p[pcnt++] = i; for (int j = 2; i*j < maxn; j++) vis[i*j] = true; } } for (int i = 0; i<pcnt; i++) { ll tmp = p[i] * p[i];//剛開始沒用p陣列沒用ll坑死 while (tmp < 1000000000000LL) { ans.push_back(tmp); tmp *= p[i]; } } sort(ans.begin(), ans.end()); } ll L, R; int main() { init(); int T; scanf("%d", &T); while (T--) { scanf("%lld%lld", &L, &R); cout << lower_bound(ans.begin(), ans.end(), R+1) - lower_bound(ans.begin(), ans.end(), L) << endl; } }