【HUST】1214 Cubic-free numbers II

题意:给定一个区间,求不能表示成k*x*x*x(x>1)的个数。

区间转化为两个1~n,可以先求出能够表示成k*x*x*x(x>1)的个数。

不妨假设x是某个素数,1~n中有n/(x^3)个值,x^3,2*x^3,……,n/(x^3)*x^3。

假设t不是素数,可以表示t=k*x。那么t^3=(k*x)^3=k^3*x^3。显然会与x统计重复。

所以,可以枚举素数的三次方,得到一个答案。

但是,6^3=(2^3)*(3^3),被计算了两次。因此,需要用到容斥原理。

 1 #include<cstdio>

 2 #include<cstring>

 3 #include<vector>

 4 #define MAXN 2650000

 5 typedef long long LL;

 6 using namespace std;

 7 vector<LL> cub;

 8 bool p[MAXN];

 9 LL tmp, limit;

10 int depth;

11 void Init() {

12     int i, j;

13     cub.clear();

14     memset(p, true, sizeof(p));

15     for (i = 2; i < 1630; i++) {

16         if (p[i]) {

17             for (j = i * i; j < MAXN; j += i)

18                 p[j] = false;

19         }

20     }

21     for (i = 2; i < MAXN; i++) {

22         if (p[i])

23             cub.push_back((LL) i * i * i);

24     }

25 }

26 void DFS(int index, int now, LL mul) {

27     if (now == depth)

28         tmp += limit / mul;

29     else {

30         int i;

31         for (i = index; cub[i] <= limit; i++) {

32             if (mul > limit / cub[i])

33                 break;

34             DFS(i + 1, now + 1, mul * cub[i]);

35         }

36     }

37 }

38 LL Count(LL n) {

39     LL ans = 0;

40     limit = n;

41     for (depth = 1;; depth++) {

42         tmp = 0;

43         DFS(0, 0, 1);

44         if (tmp) {

45             if (depth & 1)

46                 ans += tmp;

47             else

48                 ans -= tmp;

49         } else

50             break;

51     }

52     return n - ans;

53 }

54 int main() {

55     int c;

56     LL low, high;

57     Init();

58     scanf("%d", &c);

59     while (c--) {

60         scanf("%lld%lld", &low, &high);

61         printf("%lld\n", Count(high - 1) - Count(low - 1));

62     }

63     return 0;

64 }

你可能感兴趣的:(number)