I | N + NOD (N) | |
Input | Standard Input | |
Output | Standard Output |
Consider an integer sequence N where,
N0 = 1
Ni = Ni-1 + NOD(Ni-1)- for i > 0
Here, NOD(x) =number of divisors of x.
So the first few terms of this sequence are 1 2 4 7 9 12 18…
Given two integers A and B, find out the number ofintegers in the above sequence that lies within the range [A, B].
Input
The first line of input is an integer T(T < 100000), thatindicates the number of test cases. Each case contains two integers, A followed by B (1 ≤ A ≤ B ≤ 1000000).
Output
For each case, output the case numberfirst followed by the required result.
Sample Input | Sample Output |
3 1 18 1 100 3000 4000 | Case 1: 7 Case 2: 20 Case 3: 87 |
#include <cstdio>
#include <cstring>
#include <map>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 1100;
const int M = 65000;;
const int P = 200;
const int MAX = 1000001;
bool vis[N];
int a, b;
int vPrime[P], primeCnt;
int Ni[M], NiCnt;
int ans[MAX];
void input();
int solve();
void sieve_of_sundaram();
int cal(int n);
void init();
int main()
{
#ifndef ONLINE_JUDGE
freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif
init();
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++) {
input();
printf("Case %d: %d\n", i, solve());
}
return 0;
}
void sieve_of_sundaram()
{
int m = (int)sqrt(N / 2);
memset(vis, false, sizeof(vis));
for (int i = 1; i < m; i++) {
if (vis[i]) continue;
for (int j = 2 * i * (i + 1), k = 2 * i + 1; j < N; j += k) {
vis[j] = true;
}
}
primeCnt = 0;
vPrime[primeCnt++] = 2;
for (int i = 1; i < N / 2; i++) {
if (!vis[i]) vPrime[primeCnt++] = 2 * i + 1;
}
}
int cal(int n)
{
map<int, int> m;
for (int i = 0; i < primeCnt; i++) {
if (n < vPrime[i]) break;
if (n % vPrime[i] == 0) {
int cnt = 0;
while (n % vPrime[i] == 0) {
cnt++;
n /= vPrime[i];
}
m[vPrime[i]] = cnt;
}
}
if (n != 1) m[n] = 1;
int ans = 1;
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) {
ans *= (it->second + 1);
}
return ans;
}
void init()
{
sieve_of_sundaram();
NiCnt = 0;
Ni[NiCnt++] = 1;
ans[0] = 0;
ans[1] = 1;
while (true) {
int n = Ni[NiCnt - 1];
int m = n + cal(n);
if (m > 1000000) {
fill(&ans[n], &ans[1000001], NiCnt);
break;
}
fill(&ans[n], &ans[m], NiCnt);
Ni[NiCnt++] = m;
}
}
void input()
{
scanf("%d%d", &a, &b);
}
int solve()
{
return ans[b] - ans[a - 1];
}