UVa11876 - N + NOD (N)

来源:互联网 发布:游戏支付软件 编辑:程序博客网 时间:2024/05/02 04:44

I

N + NOD (N)

Input

Standard Input

Output

Standard Output

 

Consider an integer sequenceN 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


刚开始在求出1000000内的所有满足条件的序列后,然后从a到b枚举有多少个,提交总是超时。后来改成在计算满足条件的序列时,用一个数组f记录到从0到n满足条件的个数,然后有f[b] - f[a-1]得到a到b区间内满足条件的数的个数。

#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_JUDGEfreopen("d:\\OJ\\uva_in.txt", "r", stdin);#endifinit();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];}



0 0
原创粉丝点击