bhupixb

Divisors using prime factors

Aug 3rd, 2019
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.98 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cassert>
  3. #include <iostream>
  4. #include <vector>
  5. using namespace std;
  6.  
  7.  
  8. namespace IO {
  9. const int BUFFER_SIZE = 1 << 15;
  10.  
  11. char input_buffer[BUFFER_SIZE];
  12. int input_pos = 0, input_len = 0;
  13.  
  14. void _update_input_buffer() {
  15. input_len = fread(input_buffer, sizeof(char), BUFFER_SIZE, stdin);
  16. input_pos = 0;
  17.  
  18. if (input_len == 0)
  19. input_buffer[0] = EOF;
  20. }
  21.  
  22. inline char next_char(bool advance = true) {
  23. if (input_pos >= input_len)
  24. _update_input_buffer();
  25.  
  26. return input_buffer[advance ? input_pos++ : input_pos];
  27. }
  28.  
  29. template<typename T>
  30. inline void read_int(T &number) {
  31. bool negative = false;
  32. number = 0;
  33.  
  34. while (!isdigit(next_char(false)))
  35. if (next_char() == '-')
  36. negative = true;
  37.  
  38. do {
  39. number = 10 * number + (next_char() - '0');
  40. } while (isdigit(next_char(false)));
  41.  
  42. if (negative)
  43. number = -number;
  44. }
  45. }
  46.  
  47.  
  48. vector<int> smallest_factor;
  49. vector<bool> prime;
  50. vector<int> primes;
  51.  
  52. void sieve(int maximum) {
  53. maximum = max(maximum, 2);
  54. smallest_factor.assign(maximum + 1, 0);
  55. prime.assign(maximum + 1, true);
  56. prime[0] = prime[1] = false;
  57. primes = {2};
  58.  
  59. for (int p = 2; p <= maximum; p += 2) {
  60. prime[p] = p == 2;
  61. smallest_factor[p] = 2;
  62. }
  63.  
  64. for (int p = 3; p * p <= maximum; p += 2)
  65. if (prime[p])
  66. for (int i = p * p; i <= maximum; i += 2 * p)
  67. if (prime[i]) {
  68. prime[i] = false;
  69. smallest_factor[i] = p;
  70. }
  71.  
  72. for (int p = 3; p <= maximum; p += 2)
  73. if (prime[p]) {
  74. smallest_factor[p] = p;
  75. primes.push_back(p);
  76. }
  77. }
  78.  
  79.  
  80. template<typename int_array>
  81. int generate_factors(int n, int_array &&factors, bool sorted = false) {
  82. // http://oeis.org/A066150
  83. static const int FACTORS_MAX = 2000;
  84. static int buffer[FACTORS_MAX];
  85.  
  86. assert(n >= 1);
  87. int f_count = 0;
  88. factors[f_count++] = 1;
  89.  
  90. while (n != 1) {
  91. int p = smallest_factor[n], exponent = 0;
  92.  
  93. do {
  94. n /= p;
  95. exponent++;
  96. } while (n % p == 0);
  97.  
  98. int before_count = f_count;
  99.  
  100. for (int e = 1; e <= exponent; e++)
  101. for (int i = 0; i < before_count; i++) {
  102. factors[f_count] = factors[f_count - before_count] * p;
  103. f_count++;
  104. }
  105.  
  106. if (sorted && before_count > 1) {
  107. for (int section = before_count; section < f_count; section *= 2)
  108. for (int i = 0; i + section < f_count; i += 2 * section) {
  109. int length = min(2 * section, f_count - i);
  110. merge(factors + i, factors + i + section, factors + i + section, factors + i + length, buffer);
  111. copy(buffer, buffer + length, factors + i);
  112. }
  113. }
  114. }
  115.  
  116. return f_count;
  117. }
  118.  
  119.  
  120. const int N_MAX = 1e5 + 5;
  121. const int A_MAX = 1e6 + 5;
  122. const int MOD = 1e9 + 7;
  123. const int FACTORS_MAX = 1000;
  124.  
  125. int N;
  126. int factors[FACTORS_MAX];
  127. unsigned ways[N_MAX];
  128.  
  129. inline unsigned mod_add(unsigned a, unsigned b, unsigned m = MOD) {
  130. return a < m - b ? a + b : a + b - m;
  131. }
  132.  
  133. int main() {
  134. sieve(A_MAX);
  135. IO::read_int(N);
  136. ways[0] = 1;
  137. #define deb(x) cout << #x << ' ' << x << ' '
  138. for (int i = 0; i < N; i++) {
  139. int a;
  140. IO::read_int(a);
  141. int count = generate_factors(a, factors, true);
  142. deb(count);
  143. for (int f = count - 1; f >= 0; f--) {
  144. int x = factors[f];
  145. cout << x << ' ';
  146. if (x <= N)
  147. ways[x] = mod_add(ways[x], ways[x - 1]);
  148. }
  149. cout << '\n';
  150. }
  151.  
  152. long long total = 0;
  153.  
  154. for (int i = 1; i <= N; i++)
  155. total += ways[i];
  156.  
  157. printf("%lld\n", total % MOD);
  158. }
Add Comment
Please, Sign In to add comment