Advertisement
Guest User

Untitled

a guest
Jan 25th, 2020
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.21 KB | None | 0 0
  1. import java.io.*;
  2. import java.math.*;
  3. import java.util.*;
  4. import java.util.stream.*;
  5.  
  6. public class K {
  7.  
  8. interface Interactor {
  9. int getN();
  10.  
  11. int query(int[] p);
  12.  
  13. int answer(int[] p);
  14. }
  15.  
  16. static final int MAX_Q = 100_000;
  17. // static final int MAX_Q = 25_000;
  18.  
  19. class LocalInteractor implements Interactor {
  20. int[] p;
  21. int[][] m;
  22. int n;
  23.  
  24. int qryCnt = 0;
  25.  
  26. public LocalInteractor(int n) {
  27. this.n = n;
  28. p = new int[n];
  29. m = new int[n][n];
  30. for (int i = 0; i < n; i++) {
  31. int j = rand(0, i);
  32. p[i] = p[j];
  33. p[j] = i;
  34. }
  35. for (int i = 0; i < n - 1; i++) {
  36. m[p[i]][p[i + 1]] = m[p[i + 1]][p[i]] = 1;
  37. }
  38. }
  39.  
  40. boolean isPermutation(int[] a, int n) {
  41. a = a.clone();
  42. Arrays.sort(a);
  43. for (int i = 0; i < n; i++) {
  44. if (a[i] != i) {
  45. return false;
  46. }
  47. }
  48. return true;
  49. }
  50.  
  51. @Override
  52. public int getN() {
  53. return n;
  54. }
  55.  
  56. @Override
  57. public int query(int[] q) {
  58. if (!isPermutation(q, n)) {
  59. throw new AssertionError("Not a permutation");
  60. }
  61. if (++qryCnt > MAX_Q) {
  62. throw new AssertionError("Too many queries");
  63. }
  64. int ret = 0;
  65. for (int i = 0; i < n - 1; i++) {
  66. ret += m[q[i]][q[i + 1]];
  67. }
  68. return ret;
  69. }
  70.  
  71. @Override
  72. public int answer(int[] q) {
  73. if (!isPermutation(q, n)) {
  74. throw new AssertionError("Not a permutation");
  75. }
  76. boolean eq1 = true, eq2 = true;
  77. for (int i = 0; i < n; i++) {
  78. eq1 &= p[i] == q[i];
  79. eq2 &= p[i] == q[n - 1 - i];
  80. }
  81. if (!eq1 && !eq2) {
  82. throw new AssertionError("WA");
  83. }
  84. return qryCnt;
  85. }
  86. }
  87.  
  88. static int arrayLast(int[] arr) {
  89. return arr[arr.length - 1];
  90. }
  91.  
  92. int solve2(Interactor it) {
  93. int n = it.getN();
  94. if (n == 2) {
  95. return it.answer(new int[] {0, 1});
  96. }
  97. ArrayList<int[]> pieces = new ArrayList<>();
  98. for (int i = 0; i < n; i++) {
  99. pieces.add(new int[] { i });
  100. }
  101.  
  102. int[][] state = new int[n][n];
  103.  
  104. mainCycle: while (pieces.size() > 1) {
  105.  
  106. // int newCnt = ((LocalInteractor)it).qryCnt;
  107. // System.err.println((newCnt - oldCnt) + " qs used");
  108. // System.err.println(pieces.size() + " pieces left");
  109. // oldCnt = newCnt;
  110.  
  111. Collections.shuffle(pieces, rng);
  112. randomFlip(pieces);
  113.  
  114. int[] qArr = combine(pieces, 0, n);
  115. int base = it.query(qArr) - (n - pieces.size());
  116. if (base == 0) {
  117. markBadPairs(n, state, qArr);
  118. continue;
  119. }
  120.  
  121. // HARD PART !!!
  122. // Version 1: just query all the shifts.
  123. int[] res = new int[pieces.size()];
  124.  
  125. res[0] = base;
  126.  
  127. for (int i = 1; i < pieces.size(); i++) {
  128.  
  129. int newKek1 = arrayLast(pieces.get(Math.floorMod(i - 2, pieces.size())));
  130. int newKek2 = pieces.get(Math.floorMod(i - 1, pieces.size()))[0];
  131.  
  132. int oldKek1 = arrayLast(pieces.get(Math.floorMod(i - 1, pieces.size())));
  133. int oldKek2 = pieces.get(i)[0];
  134.  
  135. if (state[newKek1][newKek2] == -1 && state[oldKek1][oldKek2] == -1) {
  136. res[i] = res[i - 1];
  137. continue;
  138. }
  139.  
  140. qArr = combine(pieces, i, n);
  141. res[i] = it.query(qArr) - (n - pieces.size());
  142. if (res[i] == 0 && base == 1) {
  143. pieces.set(i - 1, merge2(pieces.get(i - 1), pieces.get(i), state));
  144. pieces.remove(i);
  145. markBadPairs(n, state, qArr);
  146. continue mainCycle;
  147. }
  148. }
  149.  
  150. int min = Integer.MAX_VALUE;
  151. for (int val : res) {
  152. min = Math.min(min, val);
  153. }
  154.  
  155. int from = 0;
  156. // res[i] == min => i and (i - 1) are connected
  157. // res[i] == max => i and (i - 1) are not connected
  158. while (res[from] == min) {
  159. from++;
  160. }
  161. for (int delta = 0; delta < pieces.size();) {
  162. int into = (from + delta - 1) % pieces.size();
  163. while (delta < pieces.size() && res[(from + delta) % pieces.size()] == min) {
  164. int idx = (from + delta) % pieces.size();
  165. pieces.set(into, merge2(pieces.get(into), pieces.get(idx), state));
  166. pieces.set(idx, null);
  167. delta++;
  168. }
  169. delta++;
  170. }
  171. for (int i = pieces.size() - 1; i >= 0; i--) {
  172. if (pieces.get(i) == null) {
  173. pieces.remove(i);
  174. }
  175. }
  176.  
  177. }
  178. return it.answer(pieces.get(0));
  179. }
  180.  
  181. void markBadPairs(int n, int[][] state, int[] qArr) {
  182. for (int i = 0; i < n - 1; i++) {
  183. int kek1 = qArr[i];
  184. int kek2 = qArr[i + 1];
  185. if (state[kek1][kek2] == 0) {
  186. state[kek1][kek2] = state[kek2][kek1] = -1;
  187. }
  188. }
  189. }
  190.  
  191. int[] merge2(int[] a, int[] b, int[][] state) {
  192. int[] ret = Arrays.copyOf(a, a.length + b.length);
  193. System.arraycopy(b, 0, ret, a.length, b.length);
  194. int kek1 = a[a.length - 1];
  195. int kek2 = b[0];
  196. state[kek1][kek2] = state[kek2][kek1] = 1;
  197. return ret;
  198. }
  199.  
  200. int solve(Interactor it) {
  201. // int wasted = 0;
  202. int n = it.getN();
  203. ArrayList<int[]> pieces = new ArrayList<>();
  204. for (int i = 0; i < n; i++) {
  205. pieces.add(new int[] { i });
  206. }
  207. // int oldCnt = 0;
  208. mainCycle: while (pieces.size() > 1) {
  209.  
  210. // int newCnt = ((LocalInteractor)it).qryCnt;
  211. // System.err.println((newCnt - oldCnt) + " qs used");
  212. // System.err.println(pieces.size() + " pieces left");
  213. // oldCnt = newCnt;
  214.  
  215. Collections.shuffle(pieces, rng);
  216. randomFlip(pieces);
  217.  
  218. int base = it.query(combine(pieces, 0, n)) - (n - pieces.size());
  219. if (base == 0) {
  220. // wasted++;
  221. continue;
  222. }
  223.  
  224. // HARD PART !!!
  225. // Version 1: just query all the shifts.
  226. int[] res = new int[pieces.size()];
  227.  
  228. res[0] = base;
  229.  
  230. for (int i = 1; i < pieces.size(); i++) {
  231. res[i] = it.query(combine(pieces, i, n)) - (n - pieces.size());
  232. if (res[i] == 0 && base == 1) {
  233. pieces.set(i - 1, merge(pieces.get(i - 1), pieces.get(i)));
  234. pieces.remove(i);
  235. continue mainCycle;
  236. }
  237. }
  238.  
  239. int min = Integer.MAX_VALUE;
  240. for (int val : res) {
  241. min = Math.min(min, val);
  242. }
  243.  
  244. int from = 0;
  245. // res[i] == min => i and (i - 1) are connected
  246. // res[i] == max => i and (i - 1) are not connected
  247. while (res[from] == min) {
  248. from++;
  249. }
  250. for (int delta = 0; delta < pieces.size();) {
  251. int into = (from + delta - 1) % pieces.size();
  252. while (delta < pieces.size() && res[(from + delta) % pieces.size()] == min) {
  253. int idx = (from + delta) % pieces.size();
  254. pieces.set(into, merge(pieces.get(into), pieces.get(idx)));
  255. pieces.set(idx, null);
  256. delta++;
  257. }
  258. delta++;
  259. }
  260. for (int i = pieces.size() - 1; i >= 0; i--) {
  261. if (pieces.get(i) == null) {
  262. pieces.remove(i);
  263. }
  264. }
  265.  
  266. }
  267. // return new int[] { it.answer(pieces.get(0)), wasted };
  268. return it.answer(pieces.get(0));
  269. }
  270.  
  271. int[] merge(int[] a, int[] b) {
  272. int[] ret = Arrays.copyOf(a, a.length + b.length);
  273. System.arraycopy(b, 0, ret, a.length, b.length);
  274. return ret;
  275. }
  276.  
  277. int[] combine(ArrayList<int[]> lst, int from, int tot) {
  278. int[] a = new int[tot];
  279. int ptr = 0;
  280. for (int i = 0; i < lst.size(); i++) {
  281. int j = (i + from) % lst.size();
  282. for (int x : lst.get(j)) {
  283. a[ptr++] = x;
  284. }
  285. }
  286. return a;
  287. }
  288.  
  289. void randomFlip(ArrayList<int[]> lst) {
  290. for (int[] arr : lst) {
  291. if (rng.nextBoolean()) {
  292. flip(arr);
  293. }
  294. }
  295. }
  296.  
  297. void flip(int[] a) {
  298. for (int i = 0, j = a.length - 1; i < j; i++, j--) {
  299. int tmp = a[i];
  300. a[i] = a[j];
  301. a[j] = tmp;
  302. }
  303. }
  304.  
  305. void submit() {
  306.  
  307. }
  308.  
  309. void test() {
  310. int worst = 0;
  311. for (int tst = 0;; tst++) {
  312. // int[] now = solve2(new LocalInteractor(400));
  313. // if (now[0] > worst) {
  314. // System.err.println(now[0] + " after " + tst);
  315. // System.err.println("wasted " + now[1]);
  316. // worst = now[0];
  317. // }
  318.  
  319. int now = solve2(new LocalInteractor(400));
  320. if (now > worst) {
  321. System.err.println(now + " after " + tst);
  322. worst = now;
  323. }
  324. }
  325. // out.println(solve2(new LocalInteractor(400)));
  326. }
  327.  
  328. void stress() {
  329. for (int tst = 0;; tst++) {
  330. if (false) {
  331. throw new AssertionError();
  332. }
  333. System.err.println(tst);
  334. }
  335. }
  336.  
  337. K() throws IOException {
  338. is = System.in;
  339. out = new PrintWriter(System.out);
  340. // submit();
  341. // stress();
  342. test();
  343. out.close();
  344. }
  345.  
  346. static final Random rng = new Random();
  347. static final int C = 5;
  348.  
  349. static int rand(int l, int r) {
  350. return l + rng.nextInt(r - l + 1);
  351. }
  352.  
  353. public static void main(String[] args) throws IOException {
  354. new K();
  355. }
  356.  
  357. private InputStream is;
  358. PrintWriter out;
  359.  
  360. private byte[] buf = new byte[1 << 14];
  361. private int bufSz = 0, bufPtr = 0;
  362.  
  363. private int readByte() {
  364. if (bufSz == -1)
  365. throw new RuntimeException("Reading past EOF");
  366. if (bufPtr >= bufSz) {
  367. bufPtr = 0;
  368. try {
  369. bufSz = is.read(buf);
  370. } catch (IOException e) {
  371. throw new RuntimeException(e);
  372. }
  373. if (bufSz <= 0)
  374. return -1;
  375. }
  376. return buf[bufPtr++];
  377. }
  378.  
  379. private boolean isTrash(int c) {
  380. return c < 33 || c > 126;
  381. }
  382.  
  383. private int skip() {
  384. int b;
  385. while ((b = readByte()) != -1 && isTrash(b))
  386. ;
  387. return b;
  388. }
  389.  
  390. String nextToken() {
  391. int b = skip();
  392. StringBuilder sb = new StringBuilder();
  393. while (!isTrash(b)) {
  394. sb.appendCodePoint(b);
  395. b = readByte();
  396. }
  397. return sb.toString();
  398. }
  399.  
  400. String nextString() {
  401. int b = readByte();
  402. StringBuilder sb = new StringBuilder();
  403. while (!isTrash(b) || b == ' ') {
  404. sb.appendCodePoint(b);
  405. b = readByte();
  406. }
  407. return sb.toString();
  408. }
  409.  
  410. double nextDouble() {
  411. return Double.parseDouble(nextToken());
  412. }
  413.  
  414. char nextChar() {
  415. return (char) skip();
  416. }
  417.  
  418. int nextInt() {
  419. int ret = 0;
  420. int b = skip();
  421. if (b != '-' && (b < '0' || b > '9')) {
  422. throw new InputMismatchException();
  423. }
  424. boolean neg = false;
  425. if (b == '-') {
  426. neg = true;
  427. b = readByte();
  428. }
  429. while (true) {
  430. if (b >= '0' && b <= '9') {
  431. ret = ret * 10 + (b - '0');
  432. } else {
  433. if (b != -1 && !isTrash(b)) {
  434. throw new InputMismatchException();
  435. }
  436. return neg ? -ret : ret;
  437. }
  438. b = readByte();
  439. }
  440. }
  441.  
  442. long nextLong() {
  443. long ret = 0;
  444. int b = skip();
  445. if (b != '-' && (b < '0' || b > '9')) {
  446. throw new InputMismatchException();
  447. }
  448. boolean neg = false;
  449. if (b == '-') {
  450. neg = true;
  451. b = readByte();
  452. }
  453. while (true) {
  454. if (b >= '0' && b <= '9') {
  455. ret = ret * 10 + (b - '0');
  456. } else {
  457. if (b != -1 && !isTrash(b)) {
  458. throw new InputMismatchException();
  459. }
  460. return neg ? -ret : ret;
  461. }
  462. b = readByte();
  463. }
  464. }
  465. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement