1. 程式人生 > >UVA-10539 打表+二分

UVA-10539 打表+二分

題意非常簡單,就是給你一個區間(閉區間),然後讓你統計區間內有多少數滿足本身不是素數,但只有一個素因子

 

首先注意題目中區間左右端點最大可以取到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;
	}
}