Advertisement
Guest User

Untitled

a guest
Mar 29th, 2020
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.53 KB | None | 0 0
  1. /*
  2. Author : quickn (quickn.ga)
  3. Email : quickwshell@gmail.com
  4. */
  5.  
  6. use std::cmp::min;
  7. use std::str;
  8. use std::io::{self, BufWriter, Write};
  9.  
  10. /// Same API as Scanner but nearly twice as fast, using horribly unsafe dark arts
  11. /// **REQUIRES** Rust 1.34 or higher
  12. pub struct UnsafeScanner<R> {
  13. reader: R,
  14. buf_str: Vec<u8>,
  15. buf_iter: str::SplitAsciiWhitespace<'static>,
  16. }
  17.  
  18. impl<R: io::BufRead> UnsafeScanner<R> {
  19. pub fn new(reader: R) -> Self {
  20. Self {
  21. reader,
  22. buf_str: Vec::new(),
  23. buf_iter: "".split_ascii_whitespace(),
  24. }
  25. }
  26.  
  27. /// This function should be marked unsafe, but noone has time for that in a
  28. /// programming contest. Use at your own risk!
  29. pub fn token<T: str::FromStr>(&mut self) -> T {
  30. loop {
  31. if let Some(token) = self.buf_iter.next() {
  32. return token.parse().ok().expect("Failed parse");
  33. }
  34. self.buf_str.clear();
  35. self.reader
  36. .read_until(b'\n', &mut self.buf_str)
  37. .expect("Failed read");
  38. self.buf_iter = unsafe {
  39. let slice = str::from_utf8_unchecked(&self.buf_str);
  40. std::mem::transmute(slice.split_ascii_whitespace())
  41. }
  42. }
  43. }
  44. }
  45.  
  46. use std::mem::MaybeUninit;
  47. use std::collections::HashMap;
  48.  
  49. //const MAX: usize = 20912792;
  50.  
  51. /*fn atkin_sieve(d: usize) -> Vec<u32> {
  52. let mut is_composite: Vec<bool> = Vec::with_capacity(d+1);
  53. let mut primes: Vec<u32> = Vec::new();
  54. is_composite.resize(d+1, false);
  55. let sqrt_d = (d as f64).sqrt().floor() as usize;
  56. let s1 = [1,7,11,13,17,19,23,29,31,37,41,43,47,49,53,59];
  57. let s2 = [1,13,17,29,37,41,49,53];
  58. let s3 = [7,19,31,43];
  59. let s4 = [11,23,47,59];
  60. for w in 0..=(d/60) {
  61. for x in s1.iter().take_while(|&&l| 60*w + l <= d) {
  62. let idx = 60*w + x;
  63. is_composite[idx] = true;
  64. }
  65. }
  66. for x in 1..=(sqrt_d>>1) {
  67. let r1 = (x*x)<<2;
  68. if r1 > d { break; }
  69. for y in (0..=(sqrt_d>>1)).map(|k| (k<<1)+1).collect::<Vec<usize>>().iter().take_while(|&&l| r1+(l*l) <= d) {
  70. let idx = r1+(y*y);
  71. if idx > d { break; }
  72. if s2.binary_search(&(idx%60)).is_ok() {
  73. is_composite[idx] = !is_composite[idx];
  74. }
  75. }
  76. }
  77. for x in (0..=(sqrt_d>>1)).map(|k| (k<<1)+1) {
  78. let r1 = (x*x)*3;
  79. if r1 > d { break; }
  80. for y in (1..=(sqrt_d>>1)).map(|k| k<<1).collect::<Vec<usize>>().iter().take_while(|&&l| r1+(l*l) <= d) {
  81. let idx = r1+(y*y);
  82. if idx > d { break; }
  83. if s3.binary_search(&(idx%60)).is_ok() {
  84. is_composite[idx] = !is_composite[idx];
  85. }
  86. }
  87. }
  88. for x in 2..=sqrt_d {
  89. let r1 = (x*x)*3;
  90. if r1 > d { break; }
  91. let mut y = x-1;
  92. loop {
  93. let idx = r1-(y*y);
  94. if s4.binary_search(&(idx%60)).is_ok() {
  95. is_composite[idx] = !is_composite[idx];
  96. }
  97. if y <= 2 { break; }
  98. y -= 2;
  99. }
  100. }
  101. for w in 0..=sqrt_d {
  102. let r1 = 60*w;
  103. if r1 > sqrt_d { break; }
  104. for x in s1.iter() {
  105. let idx = r1 + x;
  106. if idx >= 7 {
  107. if idx > sqrt_d { break; }
  108. if !is_composite[idx] {
  109. for w_p in 0..=d {
  110. if w_p*idx*idx > d { break; }
  111. for x_p in s1.iter() {
  112. let idx2 = 60*w_p + x_p;
  113. let c = idx2*idx*idx;
  114. if c > d { break; }
  115. is_composite[c] = true;
  116. }
  117. }
  118. }
  119. }
  120. }
  121. }
  122. primes.append(&mut [2, 3, 5].to_vec());
  123. for w in 0..=(d/60) {
  124. for x in s1.iter() {
  125. let idx = 60*w + x;
  126. if idx > d { break; }
  127. if idx >= 7 && !is_composite[idx] {
  128. primes.push(idx as u32);
  129. }
  130. }
  131. }
  132. primes
  133. }*/
  134.  
  135. use std::time::{Duration, SystemTime};
  136. use std::thread;
  137.  
  138. fn main() {
  139. let (stdin, stdout) = (io::stdin(), io::stdout());
  140. let mut scan = UnsafeScanner::new(stdin.lock());
  141. let mut sout = BufWriter::new(stdout.lock());
  142. let n: usize = scan.token::<usize>();
  143. let now = SystemTime::now();
  144. let d: usize = ((n<<1) as f64).powf(0.2).floor().powi(2) as usize;
  145. let sqrt_d = (d as f64).sqrt().floor() as usize;
  146. let mut mu: Box<[i8]> = vec![1;d+1].into_boxed_slice();
  147. let mut m: Box<[u32]> = vec![1;d+1].into_boxed_slice();
  148. let mut s_mu: Box<[i32]> = vec![0;d+1].into_boxed_slice();
  149. let mut is_composite: Box<[bool]> = vec![false;sqrt_d+1].into_boxed_slice();
  150. let mut primes: Vec<u32> = Vec::new();
  151. for p in 2..=sqrt_d {
  152. if !is_composite[p] { primes.push(p as u32); }
  153. for j in 0..primes.len() {
  154. let q = primes[j];
  155. let v = (q as usize)*p;
  156. if v > sqrt_d { break; }
  157. is_composite[v] = true;
  158. if p % (q as usize) == 0 { break; }
  159. }
  160. }
  161. mu[0] = 0;
  162. m[0] = 0;
  163. s_mu[1] = 1;
  164. for i in 0..primes.len() {
  165. let p = primes[i];
  166. let p_pow = (p*p) as usize;
  167. for k in 1..=d/p_pow {
  168. mu[k*p_pow] = 0;
  169. }
  170. for k in 1..=d/(p as usize) {
  171. let idx = k*(p as usize);
  172. mu[idx] *= -1;
  173. if (m[idx] as u64)*(p as u64) > (d as u64) {
  174. m[idx] = (d as u32)+1;
  175. } else {
  176. m[idx] *= p;
  177. }
  178. }
  179. }
  180. for k in 1..=d {
  181. if m[k] < (k as u32) {
  182. mu[k] *= -1;
  183. }
  184. }
  185. for p in 2..=d {
  186. s_mu[p] = s_mu[p-1] + (mu[p] as i32);
  187. }
  188. let mut hash_s_mu: HashMap<usize, i64> = HashMap::new();
  189. let mut f_mu = unsafe { MaybeUninit::zeroed().assume_init() };
  190. let rec_f_mu = &mut f_mu as *mut dyn FnMut(usize) -> i64;
  191. f_mu = |m: usize| -> i64 {
  192. if m <= d {
  193. s_mu[m] as i64
  194. } else {
  195. if let Some(&res) = hash_s_mu.get(&m) {
  196. res
  197. } else {
  198. let mut res = 1;
  199. let mut i = m;
  200. while i > 1 {
  201. let f = m/i;
  202. let next_i = m/(f+1);
  203. res -= unsafe { ((i-next_i) as i64)*(*rec_f_mu)(f) };
  204. i = next_i;
  205. }
  206. hash_s_mu.insert(m, res);
  207. res
  208. }
  209. }
  210. };
  211. let mu_cp = mu.clone();
  212. let mut hash_f: HashMap<usize, usize> = HashMap::new();
  213. let mut f = |m: usize| -> usize {
  214. if let Some(&res) = hash_f.get(&m) {
  215. res
  216. } else {
  217. //let new_d = (m as f64).powf(0.2).floor().powi(2) as usize;
  218. let mut i = (m as f64).sqrt().floor() as usize;
  219. let mut res = 0;
  220. while i > d {
  221. let f = m/(i*i);
  222. let next_i = ((m/(f+1)) as f64).sqrt().floor() as usize;
  223. res += (f_mu(i) - f_mu(next_i))*(f as i64);
  224. i = next_i;
  225. }
  226. let block = i>>2;
  227. let (s1, s2, s3, s4) = (1, block, block*2, block*3, i);
  228. let v1 = thread::spawn(move || {
  229. let r = 0;
  230. for j in s1..s2 {
  231. let f = m/(j*j);
  232. r += (mu_cp[j] as i64)*(f as i64);
  233. }
  234. });
  235. let v2 = thread::spawn(move || {
  236. let r = 0;
  237. for j in s2..=s2 {
  238. let f = m/(j*j);
  239. r += (mu_cp[j] as i64)*(f as i64);
  240. }
  241. });
  242. hash_f.insert(m, res as usize);
  243. res as usize
  244. }
  245. };
  246. let (mut l, mut r) = (n, min(n<<2, 1644934066848209910));
  247. while f(l) != f(r) && n >= f(l) && n <= f(r) {
  248. //println!("{} {}", l, r);
  249. let mid = l + ((((n - f(l)) as u128)*((r - l) as u128)) / ((f(r) - f(l)) as u128)) as usize;
  250. let func = f(mid);
  251. if func < n {
  252. l = mid + 1;
  253. } else if func > n {
  254. r = mid - 1;
  255. } else {
  256. l = mid;
  257. break;
  258. }
  259. }
  260. while f(l-1) == f(l) { l -= 1; }
  261. println!("{:?}", now.elapsed().unwrap());
  262. writeln!(sout, "{}", l).ok();
  263. //writeln!(sout, "{} {} {} {}", l, f(3), f(4), f(5)).ok();
  264. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement