Submission #1165741


Source Code Expand

// package atcoder.arc.arc069;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);

        int n = in.nextInt();
        pair = new Point[n][2];
        pt = new ArrayList<>();
        for (int i = 0; i < n ; i++) {
            for (int j = 0; j < 2 ; j++) {
                pair[i][j] = new Point(in.nextInt(), i*2+j);
                pt.add(pair[i][j]);
            }
        }
        Collections.sort(pt, (p, q) -> Long.compare(p.sortValue(), q.sortValue()));

        foundIds = new int[1000];
        M = Integer.highestOneBit(2*n-1)<<1;
        for (int i = 0 ; i < pt.size() ; i++) {
            pt.get(i).id = M-1+i;
        }
        sat = new SAT2(2*M);

        int ok = 0;
        int ng = 1000000000;
        while (ng - ok > 1) {
            int med = (ng + ok) / 2;
            if (canBuild(med)) {
                ok = med;
            } else {
                ng = med;
            }
        }

        out.println(ok);
        out.flush();
    }

    static Point[][] pair;
    static List<Point> pt;
    static SAT2 sat;
    
    private static boolean canBuild(int range) {
        sat.clear();

        for (int i = 0; i < pair.length ; i++) {
            sat.xor(pair[i][0].id, pair[i][1].id);
        }
        for (int p = 1 ; p < 2*M-2 ; p++) {
            sat.then(p, (p-1)/2);
        }

        int pn = pt.size();
        int L = 0;
        int R = 0;
        for (int i = 0 ; i < pn ; i++) {
            Point c = pt.get(i);
            int p = c.pos;
            while (L < i && pt.get(L).pos + range <= p) {
                L++;
            }
            while (R < pn && pt.get(R).pos < p + range) {
                R++;
            }

            findSegments(L, i);
            for (int j = 0; j < fn; j++) {
                sat.or(sat.not(foundIds[j]), sat.not(c.id));
            }
            findSegments(i+1, R);
            for (int j = 0; j < fn; j++) {
                sat.or(sat.not(foundIds[j]), sat.not(c.id));
            }
        }

        return sat.hasValidAssign();
    }


    static int M;

    static int fn;

    static int[] foundIds;

    static void findSegments(int ql, int qr) {
        fn = 0;
        findSegments(ql, qr, 0, 0, M);
        if (fn >= 30) {
            throw new RuntimeException();
        }
    }

    static void findSegments(int ql, int qr, int idx, int fr, int to) {
        if (qr <= fr || to <= ql) {
            return;
        }

        if (ql <= fr && to <= qr) {
            foundIds[fn++] = idx;
            return;
        }

        int med = (fr + to) / 2;
        findSegments(ql, qr, idx*2+1, fr, med);
        findSegments(ql, qr, idx*2+2, med, to);
    }

    static class Point {
        int id;
        int pos;
        int pos2;

        Point(int p, int i) {
            pos = p;
            pos2 = i;
        }

        long sortValue() {
            return (long)pos * 114514 + pos2;
        }
    }

    public static class DirectedGraph {
        int[] head;
        int[] next;
        int[] to;
        int eidx;

        public DirectedGraph(int v, int e) {
            head = new int[v];
            next = new int[e];
            to = new int[e];
            clear();
        }

        public void clear() {
            Arrays.fill(head, -1);
            eidx = 0;
        }

        public void add(int a, int b) {
            next[eidx] = head[a];
            head[a] = eidx;
            to[eidx++] = b;
        }

        public Iterable<Integer> nexts(int v) {
            final int firstE = head[v];
            return () -> new Iterator<Integer>() {
                int cursor = firstE;

                @Override
                public boolean hasNext() {
                    return cursor != -1;
                }

                @Override
                public Integer next() {
                    int ret = to[cursor];
                    cursor = next[cursor];
                    return ret;
                }
            };
        }
    }

    public static class SAT2 {
        boolean[] visited;
        int[] nodeId;
        int[] rev;
        int rvn;

        int n;
        int vn;
        DirectedGraph graph;
        DirectedGraph revGraph;

        public SAT2(int maxN) {
            n = maxN;
            vn = n * 2;

            graph = new DirectedGraph(vn, 2000000);
            revGraph = new DirectedGraph(vn, 2000000);
            nodeId = new int[vn];
            visited = new boolean[vn];
            rev = new int[vn];
        }

        public void clear() {
            Arrays.fill(nodeId, 0);
            Arrays.fill(visited, false);
            graph.clear();
            revGraph.clear();
            rvn = 0;
        }

        public int not(int v) {
            return v >= n ? v - n : v + n;
        }

        public void xor(int a, int b) {
            // a xor b => [a or b] and [(not a) or (not b)]
            or(a, b);
            or(not(a), not(b));
        }

        public void or(int a, int b) {
            // a or b => [(not a) then b] and [(not b) then a]
            then(not(a), b);
            then(not(b), a);
        }

        public void then(int a, int b) {
            graph.add(a, b);
            revGraph.add(b, a);
        }

        public void doit() {
            for (int i = 0; i < vn ; i++) {
                if (!visited[i]) {
                    dfs(i);
                }
            }
            Arrays.fill(visited, false);
            int id = 0;
            for (int i = rvn-1 ; i >= 0; i--) {
                if (!visited[rev[i]]) {
                    rdfs(rev[i], id);
                    id++;
                }
            }
        }

        private boolean hasValidAssign() {
            doit();
            for (int i = 0; i < n ; i++) {
                if (nodeId[i] == nodeId[i+n]) {
                    return false;
                }
            }
            return true;
        }

        private boolean[] findValidAssign() {
            doit();
            boolean[] ret = new boolean[n];
            for (int i = 0; i < n ; i++) {
                if (nodeId[i] == nodeId[i+n]) {
                    return null;
                }
                ret[i] = nodeId[i] > nodeId[i+n];
            }
            return ret;
        }

        private void dfs(int i) {
            visited[i] = true;
            for (int next : graph.nexts(i)) {
                if (!visited[next]) {
                    dfs(next);
                }
            }
            rev[rvn++] = i;
        }

        private void rdfs(int i, int id) {
            visited[i] = true;
            nodeId[i] = id;
            for (int next : revGraph.nexts(i)) {
                if (!visited[next]) {
                    rdfs(next, id);
                }
            }
        }
    }


    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        private int[] nextInts(int n) {
            int[] ret = new int[n];
            for (int i = 0; i < n; i++) {
                ret[i] = nextInt();
            }
            return ret;
        }

        private int[][] nextIntTable(int n, int m) {
            int[][] ret = new int[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    ret[i][j] = nextInt();
                }
            }
            return ret;
        }

        private long[] nextLongs(int n) {
            long[] ret = new long[n];
            for (int i = 0; i < n; i++) {
                ret[i] = nextLong();
            }
            return ret;
        }

        private long[][] nextLongTable(int n, int m) {
            long[][] ret = new long[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    ret[i][j] = nextLong();
                }
            }
            return ret;
        }

        private double[] nextDoubles(int n) {
            double[] ret = new double[n];
            for (int i = 0; i < n; i++) {
                ret[i] = nextDouble();
            }
            return ret;
        }

        private int next() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public char nextChar() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            if ('a' <= c && c <= 'z') {
                return (char) c;
            }
            if ('A' <= c && c <= 'Z') {
                return (char) c;
            }
            throw new InputMismatchException();
        }

        public String nextToken() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            StringBuilder res = new StringBuilder();
            do {
                res.append((char) c);
                c = next();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public int nextInt() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = next();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c-'0';
                c = next();
            } while (!isSpaceChar(c));
            return res*sgn;
        }

        public long nextLong() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            long sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = next();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c-'0';
                c = next();
            } while (!isSpaceChar(c));
            return res*sgn;
        }

        public double nextDouble() {
            return Double.valueOf(nextToken());
        }

        public boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    static void debug(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }
}

Submission Info

Submission Time
Task F - Flags
User hamadu
Language Java8 (OpenJDK 1.8.0)
Score 1200
Code Size 11648 Byte
Status AC
Exec Time 2022 ms
Memory 215544 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 1200 / 1200
Status
AC × 3
AC × 30
Set Name Test Cases
Sample 00_example_01.txt, 00_example_02.txt, 00_example_03.txt
All 00_example_01.txt, 00_example_02.txt, 00_example_03.txt, 01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt
Case Name Status Exec Time Memory
00_example_01.txt AC 172 ms 57428 KB
00_example_02.txt AC 168 ms 59348 KB
00_example_03.txt AC 181 ms 58964 KB
01.txt AC 259 ms 70528 KB
02.txt AC 230 ms 68864 KB
03.txt AC 205 ms 59452 KB
04.txt AC 202 ms 59040 KB
05.txt AC 202 ms 60788 KB
06.txt AC 1348 ms 132240 KB
07.txt AC 1270 ms 125660 KB
08.txt AC 1417 ms 131804 KB
09.txt AC 267 ms 71688 KB
10.txt AC 235 ms 70276 KB
11.txt AC 208 ms 58812 KB
12.txt AC 204 ms 61088 KB
13.txt AC 210 ms 60724 KB
14.txt AC 1257 ms 138568 KB
15.txt AC 1258 ms 134084 KB
16.txt AC 1255 ms 139440 KB
17.txt AC 280 ms 70176 KB
18.txt AC 237 ms 69912 KB
19.txt AC 1413 ms 143200 KB
20.txt AC 1446 ms 155184 KB
21.txt AC 1749 ms 168880 KB
22.txt AC 1697 ms 155792 KB
23.txt AC 2022 ms 180576 KB
24.txt AC 1645 ms 169152 KB
25.txt AC 1716 ms 215544 KB
26.txt AC 1515 ms 153120 KB
27.txt AC 170 ms 56276 KB