Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.14 KB | None | 0 0
  1. #pragma warning(disable:4996)
  2. #pragma warning(disable:4244)
  3. #pragma warning(disable:4239)
  4. #pragma warning(disable:4018)
  5.  
  6. #include <cstdio>
  7. #include <algorithm>
  8. #include <iostream>
  9. #include <stdlib.h>
  10. #include <memory>
  11. #include <vector>
  12. #include <functional>
  13. #include <array>
  14. #include <tuple>
  15. #include <cassert>
  16. #include <time.h>
  17. #include <set>
  18. #include <string>
  19. #include <ctime>
  20.  
  21. using namespace std;
  22.  
  23. typedef unsigned long long ull;
  24. typedef string Filename;
  25.  
  26. //const int BLOCK = 8000;
  27. //const int BLOCK = 15000;
  28. const int BLOCK = 3100;
  29. //const int BLOCK = 8;
  30. const int ALL_BYTES = 170000;
  31. unsigned char gl_buf[ALL_BYTES + 3000];
  32.  
  33. vector<unsigned int> ex;
  34. set<unsigned int> ss;
  35. struct RNG {
  36. int operator() (int n) {
  37. return std::rand() / (1.0 + RAND_MAX) * n;
  38. }
  39. };
  40.  
  41. //double tot_sort_time, tot_join_time;//
  42.  
  43. void prepare_file_without_memory() {
  44. FILE* input = fopen("input.bin", "wb");
  45. //setvbuf(input, NULL, _IONBF, BUFSIZ);
  46. const int n = 1000;
  47. //const int n = 5;
  48. //const int n = 650000;
  49. //const int n = 200000;//////..
  50.  
  51. fwrite(&n, 4, 1, input);
  52.  
  53. for (int i = 0; i < n; i++) {
  54. unsigned int cur = i + 1;
  55. unsigned int cur2 = (i + 1) % n + 1;
  56. fwrite(&cur, 4, 1, input);
  57. fwrite(&cur2, 4, 1, input);
  58. }
  59. fclose(input);
  60. }
  61.  
  62. void prepare_file() {
  63. FILE* input = fopen("input.bin", "wb");
  64.  
  65. const int n = 10;
  66. //const int n = 600000;
  67. //const int n = 30000;
  68. for (int i = 1; i <= n; i++) {
  69. //unsigned int cur = rand() % (1 << 30);
  70. unsigned int cur = i;
  71. if (ss.find(cur) != ss.end()) {
  72. i--;
  73. continue;
  74. }
  75. ss.insert(cur);
  76. ex.push_back(cur);
  77. }
  78. random_shuffle(ex.begin(), ex.end(), RNG());
  79. fwrite(&n, 4, 1, input);
  80.  
  81. vector<pair<int, int> > edges;
  82. for (int i = 0; i < n; i++) {
  83. //edges.push_back({ ex[i], ex[(i + 1) % n] });
  84. edges.push_back(make_pair( ex[i], ex[(i + 1) % n] ) );
  85. }
  86.  
  87. random_shuffle(edges.begin(), edges.end());
  88.  
  89. for (int i = 0; i < n; i++) {
  90. fwrite(&edges[i].first, 4, 1, input);
  91. fwrite(&edges[i].second, 4, 1, input);
  92. }
  93.  
  94. fclose(input);
  95.  
  96. int min_element_pos, min_element = (1 << 30) + 1;
  97.  
  98. for (int i = 0; i < ex.size(); i++) {
  99. if (ex[i] < min_element) {
  100. min_element = ex[i];
  101. min_element_pos = i;
  102. }
  103. }
  104. rotate(ex.begin(), ex.begin() + min_element_pos, ex.end());
  105. }
  106.  
  107. void prepare_file_test() {
  108. FILE* input = fopen("input.bin", "wb");
  109. //vector<unsigned int> v{4, 1, 2, 2, 3, 2, 4};
  110. //vector<unsigned int> v{4, 2, 3, 2, 1, 4, 2};
  111. //vector<unsigned int> v{4, 3, 2, 3, 1, 3, 4};
  112. //vector<unsigned int> v{4, 3, 2, 4, 1, 2, 4};
  113. /*vector<unsigned int> v{6, 5,
  114. 1, 2,
  115. 2, 3,
  116. 3, 4,
  117. 2, 5,
  118. 3, 5,
  119. 5,
  120. 1, 6,
  121. 2, 3,
  122. 1, 4,
  123. 4, 5,
  124. 1, 4,
  125. 1, 4};*/
  126. /*vector<unsigned int> v{10, 11,
  127. 1, 8,
  128. 7, 1,
  129. 8, 2,
  130. 7, 8,
  131. 3, 4,
  132. 3, 5,
  133. 3, 6,
  134. 3, 10,
  135. 4, 5,
  136. 4, 10,
  137. 5, 6,
  138.  
  139. 5,
  140. 1, 6,
  141. 2, 3,
  142. 5, 10,
  143. 1, 2,
  144. 5, 4,
  145. };*/
  146. vector<unsigned int> v{4, 3,
  147. 1, 3,
  148. 4, 2,
  149. 4, 3,
  150. 3,
  151. 1, 2,
  152. 1, 4,
  153. 2, 3,
  154. };
  155. fwrite(&v[0], sizeof(unsigned int), v.size(), input);
  156. fclose(input);
  157. }
  158.  
  159. void check_file(const char* filename, int ln = 1) {
  160. cerr << "---" << endl;
  161. cerr << filename << endl;
  162. FILE* input = fopen(filename, "rb");
  163. int cur;
  164. //unsigned long long cur;
  165. int cnt = 0;
  166. while (fread(&cur, 4, 1, input)) {
  167. cerr << cur << " ";
  168. cnt = (cnt + 1) % ln;
  169. if (cnt == 0) {
  170. cerr << endl;
  171. }
  172. }
  173. fclose(input);
  174. }
  175.  
  176. void check_output() {
  177. FILE* input = fopen("output.bin", "rb");
  178. unsigned int cur;
  179. vector<unsigned int> res;
  180. while (fread(&cur, 4, 1, input)) {
  181. res.push_back(cur);
  182. }
  183.  
  184. if (ex != res) {
  185. cout << "wrong" << endl;
  186. for (int i = 0; i < ex.size(); i++) {
  187. if (ex[i] != res[i]) {
  188. cout << i << " " << ex[i] << " " << res[i] << endl;
  189. }
  190. }
  191. }
  192. else {
  193. cout << "ok" << endl;
  194. }
  195. }
  196.  
  197.  
  198. struct Link {
  199. unsigned int key;
  200. unsigned int next;
  201. Link() {}
  202. Link(unsigned int k, unsigned int nx) : key(k), next(nx) {}
  203. bool operator < (const Link &A) const {
  204. if (key != A.key)
  205. return key < A.key;
  206. return next < A.next;
  207. }
  208. //~Link() = default;
  209. };
  210.  
  211. Filename get_filename(int id, const char* source) {
  212. return string(source) + to_string(static_cast<long long>(id) );
  213. }
  214.  
  215.  
  216. template<typename T>
  217. Filename do_simple_sort(int l, int r, int id, const char* filename, unsigned int offset) {
  218. T* sbuf = (T*)gl_buf;
  219. FILE* inp = fopen(filename, "rb");
  220. unsigned int uno_sz = sizeof(T);
  221. fseek(inp, l * uno_sz + offset, SEEK_SET);
  222. int sz = r - l + 1;
  223.  
  224. fread(sbuf, uno_sz, sz, inp);
  225. fclose(inp);
  226.  
  227. sort(sbuf, sbuf + sz);
  228.  
  229. Filename output_file_name_id = get_filename(id, filename);
  230.  
  231. FILE* out = fopen(output_file_name_id.c_str(), "wb");
  232. //setvbuf(out, NULL, _IONBF, BUFSIZ);
  233. fwrite(sbuf, uno_sz, sz, out);
  234. fclose(out);
  235.  
  236. return output_file_name_id;
  237. }
  238.  
  239.  
  240.  
  241. template<typename T>
  242. struct FileReader {
  243. T* buf;
  244. int len, cur_block, sz, block_size;
  245. unsigned int uno_sz;
  246. FILE* inp;
  247.  
  248. void reset(const char* filename, int w, int file_len, int block_sz) {
  249. buf = (T*)(gl_buf + w);
  250. block_size = block_sz;
  251. uno_sz = sizeof(T);
  252. len = file_len;
  253. cur_block = -1;
  254. inp = fopen(filename, "rb");
  255. load(0);
  256. }
  257.  
  258. void load(int idx) {
  259. int block = idx / block_size;
  260. if (cur_block != block) {
  261. cur_block = block;
  262. fseek(inp, uno_sz * block_size * block, SEEK_SET);
  263. sz = min(block_size, len - block * block_size);
  264. fread(buf, uno_sz, sz, inp);
  265. }
  266. }
  267.  
  268. T get(int idx) {
  269. load(idx);
  270. return buf[idx % block_size];
  271. }
  272. };
  273.  
  274.  
  275. template<typename T>
  276. Filename merge(int l, int r, const vector<Filename>& inputs, const int PARTS,
  277. const vector<int>& file_lens, int to_id, const char* filename) {
  278. //cerr << "merge " << l << " " << r << " " << to_id << " " << filename << endl;
  279. //check_file(inputs[0].c_str(), 2);
  280. //check_file(inputs[1].c_str(), 2);
  281. FileReader<T> file_readers[4];
  282.  
  283. Filename output_file_name_id = get_filename(to_id, filename);
  284. FILE* out = fopen(output_file_name_id.c_str(), "wb");
  285. //setvbuf(out, NULL, _IONBF, BUFSIZ);
  286.  
  287. const int block_sz = ALL_BYTES / sizeof(T) / (PARTS + 1);
  288. //cerr << "block_sz " << block_sz << " " << l << " " << r << endl;
  289. vector<int> cur_ptrs(PARTS);
  290.  
  291. for (int i = 0; i < PARTS; i++) {
  292. //cerr << file_lens[i] << " " << inputs[i] << endl;
  293. file_readers[i].reset(inputs[i].c_str(), sizeof(T) * i * block_sz, file_lens[i], block_sz);
  294. //setvbuf(file_readers[i].inp, NULL, _IONBF, BUFSIZ);
  295. }
  296.  
  297. T* output_buf = (T*)(gl_buf + PARTS * sizeof(T) * block_sz);
  298. int out_cnt = 0;
  299.  
  300. while (true) {
  301. int pos_min = -1;
  302. T min_element, cons;
  303. for (int i = 0; i < PARTS; i++) {
  304. if (cur_ptrs[i] < file_lens[i]) {
  305. cons = file_readers[i].get(cur_ptrs[i]);
  306. if (pos_min == -1 || cons < min_element) {
  307. min_element = cons;
  308. pos_min = i;
  309. }
  310. }
  311. }
  312. //cerr << "pos_min: " << pos_min << endl;
  313. if (pos_min == -1) {
  314. break;
  315. }
  316.  
  317. cur_ptrs[pos_min]++;
  318. //fwrite(&min_element, sizeof(T), 1, out);
  319.  
  320. output_buf[out_cnt++] = min_element;
  321. if (out_cnt == block_sz) {
  322. fwrite(output_buf, sizeof(T), out_cnt, out);
  323. out_cnt = 0;
  324. }
  325. }
  326.  
  327. if (out_cnt > 0) {
  328. fwrite(output_buf, sizeof(T), out_cnt, out);
  329. out_cnt = 0;
  330. }
  331.  
  332. fclose(out);
  333.  
  334. for (int i = 0; i < PARTS; i++) {
  335. fclose(file_readers[i].inp);
  336. }
  337. //cerr << "finished" << endl;
  338. return output_file_name_id;
  339. }
  340.  
  341. template<typename T>
  342. Filename ext_sort(int l, int r, int id, const char* filename, unsigned int offset) {
  343. //cerr << "sort " << l << " " << r << " " << id << " " << filename << " " << offset << endl;
  344. if (id == 0) {
  345. //BLOCK = ALL_BYTES / 2 / sizeof(T);
  346.  
  347. }
  348.  
  349. //clock_t begin = clock();
  350.  
  351. if (r - l + 1 <= ALL_BYTES / sizeof(T)) {
  352. Filename res = do_simple_sort<T>(l, r, id, filename, offset);
  353.  
  354. //clock_t end = clock();
  355. //double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
  356. if (id == 0) {
  357. //tot_sort_time += elapsed_secs;
  358. }
  359.  
  360. return res;
  361. }
  362. const int PARTS = 4;
  363. int all_sz = r - l + 1;
  364. int base_chunk_len = all_sz / PARTS;
  365.  
  366. vector<int> lens(PARTS);
  367. for (int i = 0; i < PARTS; i++) {
  368. lens[i] = base_chunk_len;
  369. }
  370. for (int i = 0; i < all_sz % PARTS; i++) {
  371. lens[i]++;
  372. }
  373. //cerr << "all sz chunk sz: " << all_sz << " " << chunk_sz << endl;
  374. vector<Filename> results(PARTS);
  375. int lb = l;
  376. for (int i = 0; i < PARTS; i++) {
  377. int rb = lb + lens[i] - 1;
  378. //cerr << "will call: " << lb << " " << rb << endl;
  379. results[i] = ext_sort<T>(lb, rb, id * PARTS + i + 1, filename, offset);
  380. lb += lens[i];
  381. }
  382.  
  383. Filename res = merge<T>(l, r, results, PARTS, lens, id, filename);
  384. for (int i = 0; i < PARTS; i++) {
  385. remove(results[i].c_str());
  386. }
  387. if (id == 0) {
  388. //BLOCK = 1500;
  389. }
  390.  
  391. //clock_t end = clock();
  392. //double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
  393. if (id == 0) {
  394. //tot_sort_time += elapsed_secs;
  395. }
  396.  
  397. return res;
  398. }
  399.  
  400. void prepare_link_files(const char* direct_filename, const char* reverse_filename, FILE* input_file, unsigned int n) {
  401. Link* sbuf = (Link*)gl_buf;
  402. FILE* reverse_file = fopen(reverse_filename, "wb");
  403. FILE* direct_file = fopen(direct_filename, "wb");
  404. //const int block_sz = ALL_BYTES / sizeof(Link);
  405. const int block_sz = BLOCK;
  406. for (int i = 0; i < n; i += block_sz) {
  407. int sz = min(block_sz, (int)n - i);
  408. fread(sbuf, sizeof(Link), sz, input_file);
  409.  
  410. fwrite(sbuf, sizeof(Link), sz, direct_file);
  411.  
  412. for (int j = 0; j < sz; j++) {
  413. Link& cur = sbuf[j];
  414. swap(cur.key, cur.next);
  415. }
  416.  
  417. fwrite(sbuf, sizeof(Link), sz, reverse_file);
  418.  
  419. }
  420.  
  421. fclose(reverse_file);
  422. fclose(direct_file);
  423. }
  424.  
  425. template<typename T1, typename T2, typename Tres>
  426. void join(const char* first_filename, const char* second_filename,
  427. const char* result_filename, function<Tres(const T1&, const T2&)> joiner) {
  428. const int WORK_SZ = ALL_BYTES / (sizeof(T1) + sizeof(T2) + sizeof(Tres));
  429. //clock_t begin = clock();
  430.  
  431. T1* sbuf = (T1*)gl_buf;
  432. T2* qbuf = (T2*)(gl_buf + WORK_SZ * sizeof(T1));
  433. Tres* output_buf = (Tres*)(gl_buf + WORK_SZ * (sizeof(T1) + sizeof(T2)));
  434.  
  435. unsigned int ptr1 = WORK_SZ, ptr2 = WORK_SZ;
  436. unsigned int sz1 = 0, sz2 = 0, sz_output = 0;
  437. FILE* result_file = fopen(result_filename, "wb");
  438.  
  439. FILE* t1_file = fopen(first_filename, "rb");
  440. FILE* t2_file = fopen(second_filename, "rb");
  441.  
  442. while (true) {
  443. if (ptr1 >= sz1) {
  444. sz1 = fread(sbuf, sizeof(T1), WORK_SZ, t1_file);
  445. if (sz1 <= 0) {
  446. break;
  447. }
  448. ptr1 = 0;
  449. }
  450.  
  451. if (ptr2 >= sz2) {
  452. sz2 = fread(qbuf, sizeof(T2), WORK_SZ, t2_file);
  453. if (sz2 <= 0) {
  454. break;
  455. }
  456. ptr2 = 0;
  457. }
  458.  
  459. while (ptr1 < sz1 && ptr2 < sz2 && sbuf[ptr1].key < qbuf[ptr2].key) {
  460. ptr1++;
  461. }
  462.  
  463. while (ptr2 < sz2 && ptr1 < sz1 && qbuf[ptr2].key < sbuf[ptr1].key) {
  464. ptr2++;
  465. }
  466.  
  467. if (ptr1 < sz1 && ptr2 < sz2 && sbuf[ptr1].key == qbuf[ptr2].key) {
  468. output_buf[sz_output] = joiner(sbuf[ptr1], qbuf[ptr2]);
  469. //sz_output++; ptr1++; ptr2++;
  470. sz_output++; ptr2++;
  471. if (sz_output == WORK_SZ) {
  472. fwrite(&output_buf[0], sizeof(Tres), WORK_SZ, result_file);
  473. sz_output = 0;
  474. }
  475.  
  476. }
  477.  
  478. }
  479.  
  480. if (sz_output > 0) {
  481. fwrite(&output_buf[0], sizeof(Tres), sz_output, result_file);
  482. sz_output = 0;
  483. }
  484.  
  485. fclose(result_file);
  486. fclose(t1_file);
  487. fclose(t2_file);
  488.  
  489. //clock_t end = clock();
  490. //double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
  491. //tot_join_time += elapsed_secs;
  492. }
  493.  
  494.  
  495.  
  496.  
  497.  
  498. pair<Filename, Filename> transform_input_from_irunner(const char* input_name, int& n, int& new_m, int& queries) {
  499. FILE* input = fopen(input_name, "rb");
  500.  
  501. int m;
  502. fread(&n, 4, 1, input);
  503. fread(&m, 4, 1, input);
  504.  
  505. Filename edges_input_name = get_filename(m, "edges_input");
  506. FILE* edges_input = fopen(edges_input_name.c_str(), "wb");
  507.  
  508. Link sbuf[BLOCK];
  509. new_m = 0;
  510.  
  511. for (int i = 0; i < m; i += BLOCK) {
  512. int sz = min(BLOCK, m - i);
  513. fread(sbuf, sizeof(Link), sz, input);
  514. for (int j = 0; j < sz; j++) {
  515. if (sbuf[j].key != sbuf[j].next) {
  516. new_m++;
  517. fwrite(&sbuf[j], sizeof(Link), 1, edges_input);
  518. new_m++;
  519. swap(sbuf[j].key, sbuf[j].next);
  520. fwrite(&sbuf[j], sizeof(Link), 1, edges_input);
  521. }
  522. }
  523. }
  524.  
  525.  
  526. fread(&queries, 4, 1, input);
  527. Filename queries_input_name = get_filename(queries, "queries_input");
  528. FILE* queries_input = fopen(queries_input_name.c_str(), "wb");
  529. for (int i = 0; i < queries; i += BLOCK) {
  530. int sz = min(BLOCK, queries - i);
  531. fread(sbuf, sizeof(Link), sz, input);
  532. fwrite(sbuf, sizeof(Link), sz, queries_input);
  533. }
  534.  
  535. fclose(input);
  536. fclose(edges_input);
  537. fclose(queries_input);
  538.  
  539. return make_pair(edges_input_name, queries_input_name);
  540. }
  541.  
  542. Filename choose_min_outcome(const char* edges_input_name, int m, int& out_m) {
  543. FILE* input = fopen(edges_input_name, "rb");
  544.  
  545. Filename min_outcome_name = get_filename(m, "to_who");
  546. FILE* min_outcome = fopen(min_outcome_name.c_str(), "wb");
  547.  
  548. int prev_ver = 1234567;
  549. out_m = 0;
  550. Link sbuf[BLOCK];
  551. for (int i = 0; i < m; i += BLOCK) {
  552. int sz = min(BLOCK, m - i);
  553. fread(sbuf, sizeof(Link), sz, input);
  554.  
  555. for (int j = 0; j < sz; j++) {
  556. if (prev_ver != sbuf[j].key) {
  557. prev_ver = sbuf[j].key;
  558. out_m++;
  559. fwrite(&sbuf[j], sizeof(Link), 1, min_outcome);
  560. }
  561. }
  562. }
  563.  
  564. fclose(input);
  565. fclose(min_outcome);
  566.  
  567. return min_outcome_name;
  568. }
  569.  
  570. Filename inverse_edges(const char* input_name, int m) {
  571. FILE* input = fopen(input_name, "rb");
  572. Filename output_name = get_filename(m, "inversed_edges");
  573. FILE* output = fopen(output_name.c_str(), "wb");
  574.  
  575. Link sbuf[BLOCK];
  576.  
  577. for (int i = 0; i < m; i += BLOCK) {
  578. int sz = min(BLOCK, m - i);
  579. fread(sbuf, sizeof(Link), sz, input);
  580. for (int j = 0; j < sz; j++) {
  581. swap(sbuf[j].key, sbuf[j].next);
  582. }
  583. fwrite(sbuf, sizeof(Link), sz, output);
  584. }
  585.  
  586. fclose(input);
  587. fclose(output);
  588. return output_name;
  589. }
  590.  
  591. struct NextNext {
  592. unsigned int key;
  593. unsigned int prev;
  594. unsigned int next;
  595. NextNext() {};
  596. NextNext(unsigned int a, unsigned int b, unsigned int c): key(a), prev(b), next(c) {};
  597. };
  598.  
  599. void copy_file(FILE* to, const char* from) {
  600. FILE* file_to_read = fopen(from, "rb");
  601. unsigned char* sbuf = gl_buf;
  602.  
  603. while (true) {
  604. int sz = fread(sbuf, 1, ALL_BYTES, file_to_read);
  605. if (sz <= 0) {
  606. break;
  607. }
  608. fwrite(sbuf, 1, sz, to);
  609. }
  610. fclose(file_to_read);
  611. }
  612.  
  613. Filename remove_cycle(const char* input_name, int m_now, int& acycle_m, FILE* global_prev, int& added_prevs) {
  614. FILE* input = fopen(input_name, "rb");
  615. Filename output_name = get_filename(m_now, "acycle");
  616.  
  617. FILE* output = fopen(output_name.c_str(), "wb");
  618.  
  619. acycle_m = 0;
  620.  
  621. NextNext sbuf[BLOCK];
  622. Link out;
  623. for (int i = 0; i < m_now; i += BLOCK) {
  624. int sz = min(BLOCK, m_now - i);
  625. fread(sbuf, sizeof(NextNext), sz, input);
  626. for (int j = 0; j < sz; j++) {
  627. if (sbuf[j].prev != sbuf[j].next || sbuf[j].prev > sbuf[j].key) {
  628. out = Link(sbuf[j].prev, sbuf[j].key);
  629. acycle_m++;
  630. added_prevs++;
  631. fwrite(&out, sizeof(Link), 1, output);
  632. fwrite(&out, sizeof(Link), 1, global_prev);
  633. }
  634.  
  635.  
  636. if (sbuf[j].prev == sbuf[j].next && sbuf[j].key < sbuf[j].prev) {
  637. Link root_color(sbuf[j].key, sbuf[j].key);
  638. acycle_m++;
  639. fwrite(&root_color, sizeof(Link), 1, output);
  640. }
  641. }
  642.  
  643. }
  644.  
  645. fclose(input);
  646. fclose(output);
  647.  
  648. return output_name;
  649. }
  650.  
  651.  
  652. Filename shrink_graph(const char* edges_now, int m) {
  653. Filename sorted_edges_now = ext_sort<Link>(0, m - 1, 0, edges_now, 0);
  654. Filename inversed_edges = inverse_edges(sorted_edges_now.c_str(), m);
  655. Filename sorted_inversed_edges = ext_sort<Link>(0, m - 1, 0, inversed_edges.c_str(), 0);
  656.  
  657. Filename next_next = get_filename(m, "next_next_sh");
  658. join<Link, Link, NextNext>(sorted_edges_now.c_str(),
  659. sorted_inversed_edges.c_str(),
  660. next_next.c_str(),
  661. [] (const Link& A, const Link& B) -> NextNext {
  662. return NextNext(A.key, B.next, A.next);
  663. }
  664. );
  665.  
  666. check_file(next_next.c_str(), 3);
  667.  
  668. int changes = 0;
  669. NextNext sbuf[BLOCK];
  670.  
  671. Filename new_prevs_name = get_filename(m, "new_prevs");
  672. FILE* input = fopen(next_next.c_str(), "rb");
  673. FILE* new_prevs = fopen(new_prevs_name.c_str(), "wb");
  674.  
  675. Link out;
  676.  
  677. for (int i = 0; i < m; i += BLOCK) {
  678. int sz = min(BLOCK, m - i);
  679. fread(sbuf, sizeof(NextNext), sz, input);
  680. for (int j = 0; j < sz; j++) {
  681. out = Link(sbuf[j].prev, sbuf[j].next);
  682. fwrite(&out, sizeof(Link), 1, new_prevs);
  683. changes += sbuf[j].key != sbuf[j].next;
  684. }
  685. }
  686.  
  687. fclose(new_prevs);
  688. fclose(input);
  689. cerr << "changes " << changes << endl;
  690. check_file(new_prevs_name.c_str(), 2);
  691.  
  692. if (changes == 0) {
  693. return sorted_edges_now;
  694. }
  695. else {
  696. return shrink_graph(new_prevs_name.c_str(), m);
  697. }
  698. }
  699.  
  700. struct EdgeC1 : Link {
  701. unsigned int c1;
  702. EdgeC1() {};
  703. EdgeC1(unsigned int a,
  704. unsigned int b,
  705. unsigned int c) : Link(a, b), c1(c) {};
  706. };
  707.  
  708. struct EdgeC2: EdgeC1 {
  709. unsigned int c2;
  710. EdgeC2() {};
  711. EdgeC2(unsigned int a,
  712. unsigned int b,
  713. unsigned int c,
  714. unsigned int d) : EdgeC1(a, b, c), c2(d) {};
  715.  
  716. };
  717.  
  718. Filename make_new_edges(const char* edges_now, const char* colors, int m, int& new_m) {
  719. cerr << "make_new_edges" << endl;
  720. check_file(edges_now, 2);
  721. check_file(colors, 2);
  722.  
  723. Filename edges_c1 = get_filename(m, "edges_c1");
  724. join<Link, Link, EdgeC1>(colors,
  725. edges_now,
  726. edges_c1.c_str(),
  727. [] (const Link& A, const Link& B) -> EdgeC1 {
  728. return EdgeC1(B.next, B.key, A.next);
  729. }
  730. );
  731.  
  732. check_file(edges_c1.c_str(), 3);
  733. Filename sorted_edges_c1 = ext_sort<EdgeC1>(0, m - 1, 0, edges_c1.c_str(), 0);
  734.  
  735. Filename edges_c2 = get_filename(m, "edges_c2");
  736. join<Link, EdgeC1, EdgeC2>(colors,
  737. sorted_edges_c1.c_str(),
  738. edges_c2.c_str(),
  739. [] (const Link& A, const EdgeC1& B) -> EdgeC2 {
  740. return EdgeC2(B.next, B.key, B.c1, A.next);
  741. }
  742. );
  743.  
  744. check_file(edges_c2.c_str(), 4);
  745.  
  746. FILE* edges_c2_file = fopen(edges_c2.c_str(), "rb");
  747.  
  748. Filename new_graph_name = get_filename(m, "new_gr_sh");
  749. new_m = 0;
  750.  
  751. FILE* new_graph = fopen(new_graph_name.c_str(), "wb");
  752. cerr << "m: " << m << endl;
  753. EdgeC2 sbuf[BLOCK];
  754. for (int i = 0; i < m; i += BLOCK) {
  755. int sz = min(BLOCK, m - i);
  756. fread(sbuf, sizeof(EdgeC2), sz, edges_c2_file);
  757.  
  758. for (int j = 0; j < sz; j++) {
  759. if (sbuf[j].c1 == sbuf[j].c2) {
  760. continue;
  761. }
  762. Link out(sbuf[j].c1, sbuf[j].c2);
  763. new_m++;
  764. fwrite(&out, sizeof(Link), 1, new_graph);
  765. }
  766. }
  767.  
  768. fclose(new_graph);
  769. fclose(edges_c2_file);
  770. cerr << "new_m " << new_m << endl;
  771. check_file(new_graph_name.c_str(), 2);
  772. return new_graph_name;
  773. }
  774.  
  775. void find_prevs(const char* edges_input_name, int m, FILE* global_prev, int& added_prevs) {
  776. if (m == 0) {
  777. return ;
  778. }
  779.  
  780. int out_m;
  781. Filename to_who = choose_min_outcome(edges_input_name, m, out_m);
  782. cerr << out_m << endl;
  783. check_file(to_who.c_str(), 2);
  784.  
  785. Filename inversed_edges = inverse_edges(to_who.c_str(), out_m);
  786. check_file(inversed_edges.c_str(), 2);
  787.  
  788. Filename sorted_inversed_edges = ext_sort<Link>(0, out_m - 1, 0, inversed_edges.c_str(), 0);
  789. check_file(sorted_inversed_edges.c_str(), 2);
  790.  
  791. Filename next_next = get_filename(m, "next_next_cr");
  792. join<Link, Link, NextNext>(to_who.c_str(),
  793. sorted_inversed_edges.c_str(),
  794. next_next.c_str(),
  795. [] (const Link& A, const Link& B) -> NextNext {
  796. return NextNext(A.key, B.next, A.next);
  797. }
  798. );
  799. check_file(next_next.c_str(), 3);
  800.  
  801.  
  802. int acycle_m;
  803. Filename prevs_now = remove_cycle(next_next.c_str(), out_m, acycle_m, global_prev, added_prevs);
  804.  
  805. cerr << "acycle_m " << acycle_m << endl;
  806. check_file(prevs_now.c_str(), 2);
  807.  
  808.  
  809. Filename colors_name = shrink_graph(prevs_now.c_str(), acycle_m);
  810. cerr << "colors " << endl;
  811. check_file(colors_name.c_str(), 2);
  812.  
  813. int new_m;
  814. Filename new_edges = make_new_edges(edges_input_name, colors_name.c_str(), m, new_m);
  815.  
  816. if (new_m == 0) {
  817. return ;
  818. }
  819. Filename sorted_new_edges = ext_sort<Link>(0, new_m - 1, 0, new_edges.c_str(), 0);
  820. find_prevs(sorted_new_edges.c_str(), new_m, global_prev, added_prevs);
  821. }
  822.  
  823. Filename add_roots(const char* global_now, int n, int added_prevs) {
  824. Filename sorted_global = ext_sort<Link>(0, added_prevs - 1, 0, global_now, 0);
  825. Link sbuf[BLOCK];
  826.  
  827. Filename all_prevs_name = get_filename(n, "all_prevs");
  828.  
  829. FILE* input = fopen(sorted_global.c_str(), "rb");
  830. FILE* all_prevs = fopen(all_prevs_name.c_str(), "wb");
  831.  
  832. Link cur(0, 0);
  833. Link out;
  834. bool ignore = false;
  835. for (int i = 1; i <= n; i++) {
  836. if (i > cur.key && !ignore) {
  837. int sz = fread(&cur, sizeof(Link), 1, input);
  838. if (sz == 0) {
  839. ignore = true;
  840. }
  841. }
  842. if (!ignore && i == cur.key) {
  843. fwrite(&cur, sizeof(Link), 1, all_prevs);
  844. }
  845. else {
  846. out = Link(i, i);
  847. fwrite(&out, sizeof(Link), 1, all_prevs);
  848. }
  849. }
  850.  
  851. fclose(all_prevs);
  852. fclose(input);
  853. return all_prevs_name;
  854. }
  855.  
  856.  
  857. int traverse(int start, unsigned int* to, FILE* prevs) {
  858. int len = 0;
  859. Link cur;
  860. while (true) {
  861. cerr << start << endl;
  862. to[len++] = start;
  863. fseek(prevs, sizeof(Link) * (start - 1), SEEK_SET);
  864. fread(&cur, sizeof(Link), 1, prevs);
  865. if (cur.next == start) {
  866. break;
  867. }
  868. start = cur.next;
  869. }
  870. return len;
  871. }
  872.  
  873. void answer_queries(const char* queries_input_name, int q, const char* global_prevs) {
  874. FILE* prevs = fopen(global_prevs, "rb");
  875. FILE* queries = fopen(queries_input_name, "rb");
  876. FILE* output = fopen("output.bin", "wb");
  877. Link query;
  878.  
  879. unsigned int sbuf[BLOCK];
  880. unsigned int qbuf[BLOCK];
  881. int root1, root2;
  882. for (int it = 0; it < q; it++) {
  883. fread(&query, sizeof(Link), 1, queries);
  884. cerr << "query: " << query.key << " " << query.next << endl;
  885. int len1 = traverse(query.key, sbuf, prevs);
  886. int len2 = traverse(query.next, qbuf, prevs);
  887. if (sbuf[len1 - 1] != qbuf[len2 -1]) {
  888. int minus_one = -1;
  889. cerr << "minus_one" << endl;
  890. fwrite(&minus_one, sizeof(int), 1, output);
  891. }
  892. else {
  893. int tot_len = len1 + len2 - 1;
  894. fwrite(&tot_len, sizeof(int), 1, output);
  895. cerr << "len: " << tot_len << endl;
  896. for (int i = 0; i < len1; i++) {
  897. fwrite(&sbuf[i], sizeof(int), 1, output);
  898. cerr << "out: " << sbuf[i] << endl;
  899. }
  900. for (int i = len2 - 2; i >= 0; i--) {
  901. fwrite(&qbuf[i], sizeof(int), 1, output);
  902. cerr << "out: " << qbuf[i] << endl;
  903. }
  904. }
  905. }
  906.  
  907. fclose(prevs);
  908. fclose(queries);
  909. fclose(output);
  910. }
  911.  
  912. int main() {
  913.  
  914. //srand(2327);
  915. //srand(2341);
  916. //srand(time(NULL));
  917. clock_t beg_prep = clock();
  918.  
  919. prepare_file_test();
  920. check_file("input.bin");
  921.  
  922. //prepare_file_without_memory();
  923. clock_t end_prep = clock();
  924.  
  925. int n, m, q;
  926. pair<Filename, Filename> transformed_inputs = transform_input_from_irunner("input.bin", n, m, q);
  927. cerr << n << " " << m << " " << q << endl;
  928. //check_file(transformed_inputs.first.c_str(), 2);
  929. //check_file(transformed_inputs.second.c_str(), 2);
  930.  
  931. Filename sorted_edges = ext_sort<Link>(0, m - 1, 0, transformed_inputs.first.c_str(), 0);
  932. check_file(sorted_edges.c_str(), 2);
  933.  
  934.  
  935. //cerr << "prepared in " << double(end_prep - beg_prep) / CLOCKS_PER_SEC << endl;
  936. Filename global_prev_name = get_filename(m, "global_prev");
  937. FILE* global_prev = fopen(global_prev_name.c_str(), "wb");
  938.  
  939. int added_prevs = 0;
  940. find_prevs(sorted_edges.c_str(), m, global_prev, added_prevs);
  941.  
  942. fclose(global_prev);
  943. cerr << "added_prevs " << added_prevs << endl;
  944. check_file(global_prev_name.c_str(), 2);
  945.  
  946. Filename global_prev_all = add_roots(global_prev_name.c_str(), n, added_prevs);
  947. check_file(global_prev_all.c_str(), 2);
  948.  
  949. answer_queries(transformed_inputs.second.c_str(), q, global_prev_all.c_str());
  950. check_file("output.bin");
  951. //cout << "total time: " << elapsed_secs << endl;
  952. //cout << "total sort time: " << tot_sort_time << endl;
  953. //cout << "total join time: " << tot_join_time << endl;
  954. //cout << "total flip coins: " << tot_flip_coins << endl;
  955.  
  956. //check_output();
  957. return 0;
  958. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement