E2. String Coloring (hard version)time limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputThis is a hard version of the problem. The actual problems are different; but the easy version is almost a subtask of the hard version. Note that the constraints and the output format are different.You are given a string ss consisting of nn lowercase Latin letters.You have to color all its characters the minimum number of colors (each character to exactly one color, the same letters can be colored the same or different colors, i.e. you can choose exactly one color for each index in ss).After coloring, you can swap any two neighboring characters of the string that are colored different colors. You can perform such an operation arbitrary (possibly, zero) number of times.The goal is to make the string sorted, i.e. all characters should be in alphabetical order.Your task is to find the minimum number of colors which you have to color the given string in so that after coloring it can become sorted by some sequence of swaps. Note that you have to restore only coloring, not the sequence of swaps.InputThe first line of the input contains one integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the length of ss.The second line of the input contains the string ss consisting of exactly nn lowercase Latin letters.OutputIn the first line print one integer resres (1≤res≤n1≤res≤n) — the minimum number of colors in which you have to color the given string so that after coloring it can become sorted by some sequence of swaps.In the second line print any possible coloring that can be used to sort the string using some sequence of swaps described in the problem statement. The coloring is the array cc of length nn, where 1≤ci≤res1≤ci≤res and cici means the color of the ii-th character.ExamplesInputCopy9
abacbecfd
OutputCopy2
1 1 2 1 2 1 2 1 2
InputCopy8
aaabbcbb
OutputCopy2
1 2 1 2 1 2 1 1
InputCopy7
abcdedc
OutputCopy3
1 1 1 1 1 2 3
InputCopy5
abcde
OutputCopy1
1 1 1 1 1

import java.io.*;

import java.util.*;

public class Task {

    public static void main(String[] args) throws Exception {

        new Task().go();

    }

    PrintWriter out;

    Reader in;

    BufferedReader br;

    Task() throws IOException {

        try {

            //br = new BufferedReader( new FileReader("input.txt") );

            //in = new Reader("input.txt");

            in = new Reader("input.txt");

            out = new PrintWriter( new BufferedWriter(new FileWriter("output.txt")) );

        }

        catch (Exception e) {

            //br = new BufferedReader( new InputStreamReader( System.in ) );

            in = new Reader();

            out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(System.out)) );

        }

    }

    void go() throws Exception {

        //int t = in.nextInt();

        int t = 1;

        while (t > 0) {

            solve();

            t--;

        }

        out.flush();

        out.close();

    }

    int inf = 2000000000;

    int mod = 1000000007;

    double eps = 0.000000001;

    int n;

    int m;

    ArrayList<Integer>[] g;

    void solve() throws IOException {

        int n = in.nextInt();

        String s = in.next();

        int[] a = new int[n];

        int cnt = 1;

        int[] d = new int[26];

        for (int i = 0; i < n; i++) {

            int ch = s.charAt(i) - 'a';

            d[ch] = 1;

            for (int j = ch + 1; j < 26; j++)

                d[ch] = Math.max(d[ch], d[j] + 1);

            cnt = Math.max(cnt, d[ch]);

            a[i] = d[ch];

        }

        out.println(cnt);

        for (int i = 0; i < n; i++)

            out.print(a[i] + " ");

    }

    class Pair implements Comparable<Pair> {

        int a;

        int b;

        Pair(int a, int b) {

            this.a = a;

            this.b = b;

        }

        public int compareTo(Pair p) {

            if (a != p.a)

                return Integer.compare(a, p.a);

            else

                return Integer.compare(-b, -p.b);

        }

    }

    class Item {

        int a;

        int b;

        int c;

        Item(int a, int b, int c) {

            this.a = a;

            this.b = b;

            this.c = c;

        }

    }

    class Reader {

        BufferedReader  br;

        StringTokenizer tok;

        Reader(String file) throws IOException {

            br = new BufferedReader( new FileReader(file) );

        }

        Reader() throws IOException {

            br = new BufferedReader( new InputStreamReader(System.in) );

        }

        String next() throws IOException {

            while (tok == null || !tok.hasMoreElements())

                tok = new StringTokenizer(br.readLine());

            return tok.nextToken();

        }

        int nextInt() throws NumberFormatException, IOException {

            return Integer.valueOf(next());

        }

        long nextLong() throws NumberFormatException, IOException {

            return Long.valueOf(next());

        }

        double nextDouble() throws NumberFormatException, IOException {

            return Double.valueOf(next());

        }

        String nextLine() throws IOException {

            return br.readLine();

        }

    }

    static class InputReader

    {

        final private int BUFFER_SIZE = 1 << 16;

        private DataInputStream din;

        private byte[] buffer;

        private int bufferPointer, bytesRead;

        public InputReader()

        {

            din = new DataInputStream(System.in);

            buffer = new byte[BUFFER_SIZE];

            bufferPointer = bytesRead = 0;

        }

        public InputReader(String file_name) throws IOException

        {

            din = new DataInputStream(new FileInputStream(file_name));

            buffer = new byte[BUFFER_SIZE];

            bufferPointer = bytesRead = 0;

        }

        public String readLine() throws IOException

        {

            byte[] buf = new byte[64]; // line length

            int cnt = 0, c;

            while ((c = read()) != -1)

            {

                if (c == '\n')

                    break;

                buf[cnt++] = (byte) c;

            }

            return new String(buf, 0, cnt);

        }

        public int nextInt() throws IOException

        {

            int ret = 0;

            byte c = read();

            while (c <= ' ')

                c = read();

            boolean neg = (c == '-');

            if (neg)

                c = read();

            do

            {

                ret = ret * 10 + c - '0';

            }  while ((c = read()) >= '0' && c <= '9');

            if (neg)

                return -ret;

            return ret;

        }

        public long nextLong() throws IOException

        {

            long ret = 0;

            byte c = read();

            while (c <= ' ')

                c = read();

            boolean neg = (c == '-');

            if (neg)

                c = read();

            do {

                ret = ret * 10 + c - '0';

            }

            while ((c = read()) >= '0' && c <= '9');

            if (neg)

                return -ret;

            return ret;

        }

        public double nextDouble() throws IOException

        {

            double ret = 0, div = 1;

            byte c = read();

            while (c <= ' ')

                c = read();

            boolean neg = (c == '-');

            if (neg)

                c = read();

            do {

                ret = ret * 10 + c - '0';

            }

            while ((c = read()) >= '0' && c <= '9');

            if (c == '.')

            {

                while ((c = read()) >= '0' && c <= '9')

                {

                    ret += (c - '0') / (div *= 10);

                }

            }

            if (neg)

                return -ret;

            return ret;

        }

        private void fillBuffer() throws IOException

        {

            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);

            if (bytesRead == -1)

                buffer[0] = -1;

        }

        private byte read() throws IOException

        {

            if (bufferPointer == bytesRead)

                fillBuffer();

            return buffer[bufferPointer++];

        }

        public void close() throws IOException

        {

            if (din == null)

                return;

            din.close();

        }

    }

}


A. Recommendationstime limit per test2 secondsmemory limit per test512 megabytesinputstandard inputoutputstandard outputVK news recommendation system daily selects interesting publications of one of nn disjoint categories for each user. Each publication belongs to exactly one category. For each category ii batch algorithm selects aiai publications.The latest A/B test suggests that users are reading recommended publications more actively if each category has a different number of publications within daily recommendations. The targeted algorithm can find a single interesting publication of ii-th category within titi seconds. What is the minimum total time necessary to add publications to the result of batch algorithm execution, so all categories have a different number of publications? You can't remove publications recommended by the batch algorithm.InputThe first line of input consists of single integer nn — the number of news categories (1≤n≤2000001≤n≤200000).The second line of input consists of nn integers aiai — the number of publications of ii-th category selected by the batch algorithm (1≤ai≤1091≤ai≤109).The third line of input consists of nn integers titi — time it takes for targeted algorithm to find one new publication of category ii (1≤ti≤105)1≤ti≤105).OutputPrint one integer — the minimal required time for the targeted algorithm to get rid of categories with the same size.ExamplesInputCopy5
3 7 9 7 8
5 2 5 7 5
OutputCopy6
InputCopy5
1 2 3 4 5
1 1 1 1 1
OutputCopy0
NoteIn the first example; it is possible to find three publications of the second type; which will take 6 seconds.In the second example; all news categories contain a different number of publications.

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author Nikita Gorokhov <wackloner@yandex-team.ru>
 */
public class A1310 {

    // 420 remainder: use long everywhere

    private final static boolean MULTIPLE_TESTS = false;

    private FastReader reader;
    private FastWriter writer;

    private void solve() {
        int n = reader.readInt();
        int[] a = reader.readIntArray(n);
        int[] t = reader.readIntArray(n);

        var sorted = IntStream.range(0, n)
                .mapToObj(i -> Tuple.Tuple2.of(a[i], t[i]))
                .sorted()
                .collect(Collectors.toList());

        TreeMap<Integer, Integer> multiset = new TreeMap<>();
        long sumInSet = 0;
        long ans = 0;
        int last = -1;
        for (int i = 0; i < n; i++) {
            var cur = sorted.get(i);

            if (cur.first != last) {
                while (!multiset.isEmpty() && last < cur.first) {
                    var max = multiset.lastEntry();
                    var newVal = max.getValue() - 1;
                    sumInSet -= max.getKey();
                    if (newVal == 0) {
                        multiset.remove(max.getKey());
                    } else {
                        multiset.put(max.getKey(), max.getValue() - 1);
                    }
                    ans += sumInSet;
                    last++;
                }

                last = cur.first;
            }

            multiset.put(cur.second, multiset.getOrDefault(cur.second, 0) + 1);
            sumInSet += cur.second;
        }

        while (!multiset.isEmpty()) {
            var max = multiset.lastEntry();
            var newVal = max.getValue() - 1;
            sumInSet -= max.getKey();
            if (newVal == 0) {
                multiset.remove(max.getKey());
            } else {
                multiset.put(max.getKey(), max.getValue() - 1);
            }
            ans += sumInSet;
            last++;
        }

        writer.print(ans);
    }

    private void run() throws Exception {
        reader = new FastReader();
        writer = new FastWriter();

        int t = MULTIPLE_TESTS ? reader.readInt() : 1;

        for (int testNum = 0; testNum < t; testNum++) {
            solve();
        }

        writer.close();
        reader.close();
    }

    public static void main(String[] args) throws Exception {
        new A1310().run();
    }

    private final static boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;

    private static class FastWriter implements AutoCloseable {
        @SuppressWarnings(value="all")
        private final static Optional<String> OUTPUT_FILENAME = Optional.empty();

        private final PrintWriter out;

        public FastWriter() throws FileNotFoundException {
            this.out = OUTPUT_FILENAME.isEmpty() ? new PrintWriter(System.out) : new PrintWriter(new File(OUTPUT_FILENAME.get()));
        }

        public void print(int value) {
            out.print(value);
        }

        public void print(long value) {
            out.print(value);
        }

        public void print(double value) {
            out.print(value);
        }

        public <T> void print(T value) {
            out.print(value);
        }

        public void println(int value) {
            out.println(value);
        }

        public void println(long value) {
            out.println(value);
        }

        public void println(double value) {
            out.println(value);
        }

        public <T> void println(T value) {
            out.println(value);
        }

        public <T> void printArray(T[] array) {
            for (int i = 0; i < array.length; i++) {
                out.print(array[i]);
                if (i + 1 < array.length) {
                    out.print(' ');
                }
            }
            out.println();
        }

        public void printArray(int[] array) {
            for (int i = 0; i < array.length; i++) {
                out.print(array[i]);
                if (i + 1 < array.length) {
                    out.print(' ');
                }
            }
            out.println();
        }

        public void printArray(long[] array) {
            for (int i = 0; i < array.length; i++) {
                out.print(array[i]);
                if (i + 1 < array.length) {
                    out.print(' ');
                }
            }
            out.println();
        }

        public void printArray(double[] array) {
            for (int i = 0; i < array.length; i++) {
                out.print(array[i]);
                if (i + 1 < array.length) {
                    out.print(' ');
                }
            }
            out.println();
        }

        @Override
        public void close() {
            out.close();
        }
    }

    private static class FastReader implements AutoCloseable {
        private final static String INPUT_FILENAME = "input.txt";

        private final InputStream inputStream;
        private final byte[] buffer = new byte[1024];

        private int bufferLen = 0;
        private int bufferPtr = 0;

        public FastReader() throws FileNotFoundException {
            this.inputStream = ONLINE_JUDGE ? System.in : new FileInputStream(INPUT_FILENAME);
        }

        public int[] readIntArray(int size) {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = readInt();
            }
            return array;
        }

        public long[] readLongArray(int size) {
            long[] array = new long[size];
            for (int i = 0; i < size; i++) {
                array[i] = readLong();
            }
            return array;
        }

        public double[] readDoubleArray(int size) {
            double[] array = new double[size];
            for (int i = 0; i < size; i++) {
                array[i] = readLong();
            }
            return array;
        }

        public double readDouble() {
            return Double.parseDouble(readToken());
        }

        public String readToken() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while (!(isSpaceChar(b))) {
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        public int readInt() {
            int num = 0, b;
            boolean minus = false;

            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));

            if (b == '-') {
                minus = true;
                b = readByte();
            }

            while (true) {
                if (b >= '0' && b <= '9') {
                    num = num * 10 + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public long readLong() {
            long num = 0;
            int b;
            boolean minus = false;

            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));

            if (b == '-') {
                minus = true;
                b = readByte();
            }

            while (true) {
                if (b >= '0' && b <= '9') {
                    num = num * 10 + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public int readByte() {
            if (bufferLen == -1) {
                throw new InputMismatchException();
            }
            if (bufferPtr >= bufferLen) {
                bufferPtr = 0;
                try {
                    bufferLen = inputStream.read(buffer);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (bufferLen <= 0) {
                    return -1;
                }
            }
            return buffer[bufferPtr++];
        }

        public char readChar() {
            return (char) skip();
        }

        private int skip() {
            int b;
            while ((b = readByte()) != -1 && isSpaceChar(b));
            return b;
        }

        private static boolean isSpaceChar(int c) {
            return !(c >= 33 && c <= 126);
        }

        @Override
        public void close() throws Exception {
            inputStream.close();
            bufferPtr = bufferLen;
        }
    }

    private static class Tuple {
        public static <A, B> Tuple2<A, B> of(A first, B second) {
            return new Tuple2<>(first, second);
        }

        public static <A extends Comparable<A>, B extends Comparable<B>> Tuple2<A, B> of(A first, B second) {
            return new ComparableTuple2<>(first, second);
        }

        public static <A, B, C> Tuple3<A, B, C> of(A first, B second, C third) {
            return new Tuple3<>(first, second, third);
        }

        public static <A extends Comparable<A>, B extends Comparable<B>, C extends Comparable<C>> Tuple3<A, B, C> of(A first, B second, C third) {
            return new ComparableTuple3<>(first, second, third);
        }

        private static class Tuple2<A, B> extends Tuple {
            public final A first;
            public final B second;

            private Tuple2(A first, B second) {
                this.first = first;
                this.second = second;
            }

            @Override
            public String toString() {
                return "(" + first + ", " + second + ")";
            }
        }

        private static class Tuple3<A, B, C> extends Tuple2<A, B> {
            public final C third;

            private Tuple3(A first, B second, C third) {
                super(first, second);
                this.third = third;
            }

            @Override
            public String toString() {
                return "(" + first + ", " + second + ", " + third + ")";
            }
        }

        private static class ComparableTuple2<A extends Comparable<A>, B extends Comparable<B>> extends Tuple2<A, B> implements Comparable<ComparableTuple2<A, B>> {
            private ComparableTuple2(A first, B second) {
                super(first, second);
            }

            @Override
            @SuppressWarnings("unchecked")
            public int compareTo(ComparableTuple2 that) {
                var res = first.compareTo((A) that.first);
                return res == 0 ? second.compareTo((B) that.second) : res;
            }
        }

        private static class ComparableTuple3<A extends Comparable<A>, B extends Comparable<B>, C extends Comparable<C>>
                extends Tuple3<A, B, C> implements Comparable<ComparableTuple3<A, B, C>> {

            private ComparableTuple3(A first, B second, C third) {
                super(first, second, third);
            }

            @Override
            @SuppressWarnings("unchecked")
            public int compareTo(ComparableTuple3 that) {
                var firstR = first.compareTo((A) that.first);
                if (firstR == 0) {
                    var secondR = second.compareTo((B) that.second);
                    if (secondR == 0) {
                        return third.compareTo((C) that.third);
                    }
                    return secondR;
                }
                return firstR;
            }
        }
    }

    private static class Utils {
        private static final Random random = new Random(System.nanoTime());

        public static <T extends Comparable<T>> void sort(T[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static void sort(int[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static void sort(long[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static void sort(double[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static <T> void sort(T[] array, Comparator<T> comparator) {
            shuffle(array);
            Arrays.sort(array, comparator);
        }

        public static <T> void shuffle(T[] array) {
            for (int i = array.length - 1; i > 0; i--) {
                int index = random.nextInt(i + 1);
                T a = array[index];
                array[index] = array[i];
                array[i] = a;
            }
        }

        public static void shuffle(int[] array) {
            for (int i = array.length - 1; i > 0; i--) {
                int index = random.nextInt(i + 1);
                int a = array[index];
                array[index] = array[i];
                array[i] = a;
            }
        }

        public static void shuffle(long[] array) {
            for (int i = array.length - 1; i > 0; i--) {
                int index = random.nextInt(i + 1);
                long a = array[index];
                array[index] = array[i];
                array[i] = a;
            }
        }

        public static void shuffle(double[] array) {
            for (int i = array.length - 1; i > 0; i--) {
                int index = random.nextInt(i + 1);
                double a = array[index];
                array[index] = array[i];
                array[i] = a;
            }
        }

        public static <T extends Comparable<T>> void sort(List<T> list) {
            Collections.shuffle(list);
            Collections.sort(list);
        }

        public static <T> void sort(List<T> list, Comparator<T> comparator) {
            Collections.shuffle(list);
            list.sort(comparator);
        }

        public static int randomInt(int fromIncluded, int toExcluded) {
            return fromIncluded + random.nextInt(toExcluded - fromIncluded);
        }
    }
}


B. Yet Another Palindrome Problemtime limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputYou are given an array aa consisting of nn integers.Your task is to determine if aa has some subsequence of length at least 33 that is a palindrome.Recall that an array bb is called a subsequence of the array aa if bb can be obtained by removing some (possibly, zero) elements from aa (not necessarily consecutive) without changing the order of remaining elements. For example, [2][2], [1,2,1,3][1,2,1,3] and [2,3][2,3] are subsequences of [1,2,1,3][1,2,1,3], but [1,1,2][1,1,2] and [4][4] are not.Also, recall that a palindrome is an array that reads the same backward as forward. In other words, the array aa of length nn is the palindrome if ai=an−i−1ai=an−i−1 for all ii from 11 to nn. For example, arrays [1234][1234], [1,2,1][1,2,1], [1,3,2,2,3,1][1,3,2,2,3,1] and [10,100,10][10,100,10] are palindromes, but arrays [1,2][1,2] and [1,2,3,1][1,2,3,1] are not.You have to answer tt independent test cases.InputThe first line of the input contains one integer tt (1≤t≤1001≤t≤100) — the number of test cases.Next 2t2t lines describe test cases. The first line of the test case contains one integer nn (3≤n≤50003≤n≤5000) — the length of aa. The second line of the test case contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n1≤ai≤n), where aiai is the ii-th element of aa.It is guaranteed that the sum of nn over all test cases does not exceed 50005000 (∑n≤5000∑n≤5000).OutputFor each test case, print the answer — "YES" (without quotes) if aa has some subsequence of length at least 33 that is a palindrome and "NO" otherwise.ExampleInputCopy5
3
1 2 1
5
1 2 2 3 2
3
1 1 2
4
1 2 2 1
10
1 1 2 2 3 3 4 4 5 5
OutputCopyYES
YES
NO
YES
NO
NoteIn the first test case of the example; the array aa has a subsequence [1,2,1][1,2,1] which is a palindrome.In the second test case of the example, the array aa has two subsequences of length 33 which are palindromes: [2,3,2][2,3,2] and [2,2,2][2,2,2].In the third test case of the example, the array aa has no subsequences of length at least 33 which are palindromes.In the fourth test case of the example, the array aa has one subsequence of length 44 which is a palindrome: [1,2,2,1][1,2,2,1] (and has two subsequences of length 33 which are palindromes: both are [1,2,1][1,2,1]).In the fifth test case of the example, the array aa has no subsequences of length at least 33 which are palindromes.

import java.util.*;

import java.io.*;

public class A {

	static class Pair {

		int x;

		int y;

		public Pair(int x, int y) {

			this.x = x;

			this.y = y;

		}

	}

	public static void main(String[] args) throws IOException {

		Scanner sc = new Scanner(System.in);

		StringBuilder str = new StringBuilder();

		int t = sc.nextInt();

		for (int xx = 1; xx <= t; xx++) {

			int n = sc.nextInt();

			int[] arr = new int[n];

			for (int i = 0; i < n; i++)

				arr[i] = sc.nextInt();

			boolean ok = false;

			HashMap<Integer, Integer> map = new HashMap<>();

			for (int i = 0; i < n; i++) {

				if (map.containsKey(arr[i])) {

					if (i - map.get(arr[i]) > 1)

						ok = true;

				} else

					map.put(arr[i], i);

			}

			if (ok)

				str.append("YES" + "\n");

			else

				str.append("NO" + "\n");

		}

		System.out.println(str);

		sc.close();

	}

}


D. Dr. Evil Underscorestime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputToday; as a friendship gift, Bakry gave Badawy nn integers a1,a2,…,ana1,a2,…,an and challenged him to choose an integer XX such that the value max1≤i≤n(ai⊕X)max1≤i≤n(ai⊕X) is minimum possible, where ⊕⊕ denotes the bitwise XOR operation.As always, Badawy is too lazy, so you decided to help him and find the minimum possible value of max1≤i≤n(ai⊕X)max1≤i≤n(ai⊕X).InputThe first line contains integer nn (1≤n≤1051≤n≤105).The second line contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤230−10≤ai≤230−1).OutputPrint one integer — the minimum possible value of max1≤i≤n(ai⊕X)max1≤i≤n(ai⊕X).ExamplesInputCopy3
1 2 3
OutputCopy2
InputCopy2
1 5
OutputCopy4
NoteIn the first sample; we can choose X=3X=3.In the second sample, we can choose X=5X=5.

import java.io.*;

import java.math.BigInteger;

import java.util.*;

public class Main {

    static int MOD = 1000000007;

    // After writing solution, quick scan for:

    //   array out of bounds

    //   special cases e.g. n=1?

    //   npe, particularly in maps

    //

    // Big numbers arithmetic bugs:

    //   int overflow

    //   sorting, or taking max, after MOD

    void solve() throws IOException {

        int n = ri();

        int[] a = ril(n);

        Node root = new Node();

        for (int ai : a) {

            Node curr = root;

            for (int b = 29; b >= 0; b--) {

                int bit = ((1 << b) & ai) > 0 ? 1 : 0;

                if (bit == 0) {

                    if (curr.zero == null) curr.zero = new Node();

                    curr = curr.zero;

                } else {

                    if (curr.one == null) curr.one = new Node();

                    curr = curr.one;

                }

            }

        }

        dfs(root, 29, 0);

        pw.println(ans);

    }

    // IMPORTANT

    // DID YOU CHECK THE COMMON MISTAKES ABOVE?

    int ans = Integer.MAX_VALUE;

    void dfs(Node curr, int b, int sofar) {

        if (b < 0) {

            ans = Math.min(ans, sofar);

            return;

        }

        if (curr.zero == null) {

            dfs(curr.one, b-1, sofar);

        } else if (curr.one == null) {

            dfs(curr.zero, b-1, sofar);

        } else {

            sofar = sofar | (1 << b);

            dfs(curr.one, b-1, sofar);

            dfs(curr.zero, b-1, sofar);

        }

    }

    // Template code below

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    PrintWriter pw = new PrintWriter(System.out);

    public static void main(String[] args) throws IOException {

        Main m = new Main();

        m.solve();

        m.close();

    }

    void close() throws IOException {

        pw.flush();

        pw.close();

        br.close();

    }

    int ri() throws IOException {

        return Integer.parseInt(br.readLine().trim());

    }

    long rl() throws IOException {

        return Long.parseLong(br.readLine().trim());

    }

    int[] ril(int n) throws IOException {

        int[] nums = new int[n];

        int c = 0;

        for (int i = 0; i < n; i++) {

            int sign = 1;

            c = br.read();

            int x = 0;

            if (c == '-') {

                sign = -1;

                c = br.read();

            }

            while (c >= '0' && c <= '9') {

                x = x * 10 + c - '0';

                c = br.read();

            }

            nums[i] = x * sign;

        }

        while (c != '\n' && c != -1) c = br.read();

        return nums;

    }

    long[] rll(int n) throws IOException {

        long[] nums = new long[n];

        int c = 0;

        for (int i = 0; i < n; i++) {

            int sign = 1;

            c = br.read();

            long x = 0;

            if (c == '-') {

                sign = -1;

                c = br.read();

            }

            while (c >= '0' && c <= '9') {

                x = x * 10 + c - '0';

                c = br.read();

            }

            nums[i] = x * sign;

        }

        while (c != '\n' && c != -1) c = br.read();

        return nums;

    }

    int[] rkil() throws IOException {

        int sign = 1;

        int c = br.read();

        int x = 0;

        if (c == '-') {

            sign = -1;

            c = br.read();

        }

        while (c >= '0' && c <= '9') {

            x = x * 10 + c - '0';

            c = br.read();

        }

        return ril(x);

    }

    long[] rkll() throws IOException {

        int sign = 1;

        int c = br.read();

        int x = 0;

        if (c == '-') {

            sign = -1;

            c = br.read();

        }

        while (c >= '0' && c <= '9') {

            x = x * 10 + c - '0';

            c = br.read();

        }

        return rll(x);

    }

    char[] rs() throws IOException {

        return br.readLine().toCharArray();

    }

    void sort(int[] A) {

        Random r = new Random();

        for (int i = A.length-1; i > 0; i--) {

            int j = r.nextInt(i+1);

            int temp = A[i];

            A[i] = A[j];

            A[j] = temp;

        }

        Arrays.sort(A);

    }

    void printDouble(double d) {

        pw.printf("%.16f", d);

    }

}

class Node {

    Node zero;

    Node one;

}


C2. Madhouse (Hard version)time limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputThis problem is different with easy version only by constraints on total answers lengthIt is an interactive problemVenya joined a tour to the madhouse; in which orderlies play with patients the following game. Orderlies pick a string ss of length nn, consisting only of lowercase English letters. The player can ask two types of queries:   ? l r – ask to list all substrings of s[l..r]s[l..r]. Substrings will be returned in random order, and in every substring, all characters will be randomly shuffled.  ! s – guess the string picked by the orderlies. This query can be asked exactly once, after that the game will finish. If the string is guessed correctly, the player wins, otherwise he loses. The player can ask no more than 33 queries of the first type.To make it easier for the orderlies, there is an additional limitation: the total number of returned substrings in all queries of the first type must not exceed ⌈0.777(n+1)2⌉⌈0.777(n+1)2⌉ (⌈x⌉⌈x⌉ is xx rounded up).Venya asked you to write a program, which will guess the string by interacting with the orderlies' program and acting by the game's rules.Your program should immediately terminate after guessing the string using a query of the second type. In case your program guessed the string incorrectly, or it violated the game rules, it will receive verdict Wrong answer.Note that in every test case the string is fixed beforehand and will not change during the game, which means that the interactor is not adaptive.InputFirst line contains number nn (1≤n≤1001≤n≤100) — the length of the picked string.InteractionYou start the interaction by reading the number nn.To ask a query about a substring from ll to rr inclusively (1≤l≤r≤n1≤l≤r≤n), you should output? l ron a separate line. After this, all substrings of s[l..r]s[l..r] will be returned in random order, each substring exactly once. In every returned substring all characters will be randomly shuffled.In the case, if you ask an incorrect query, ask more than 33 queries of the first type or there will be more than ⌈0.777(n+1)2⌉⌈0.777(n+1)2⌉ substrings returned in total, you will receive verdict Wrong answer.To guess the string ss, you should output! son a separate line.After printing each query, do not forget to flush the output. Otherwise, you will get Idleness limit exceeded. To flush the output, you can use:   fflush(stdout) or cout.flush() in C++;  System.out.flush() in Java;  flush(output) in Pascal;  stdout.flush() in Python;  see documentation for other languages. If you received - (dash) as an answer to any query, you need to terminate your program with exit code 0 (for example, by calling exit(0)). This means that there was an error in the interaction protocol. If you don't terminate with exit code 0, you can receive any unsuccessful verdict. Hack formatTo hack a solution, use the following format:The first line should contain one integer nn (1≤n≤1001≤n≤100) — the length of the string, and the following line should contain the string ss.ExampleInputCopy4

a
aa
a

cb
b
c

cOutputCopy? 1 2

? 3 4

? 4 4

! aabc

import java.io.OutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.BufferedOutputStream;

import java.io.UncheckedIOException;

import java.nio.charset.Charset;

import java.util.StringTokenizer;

import java.io.Writer;

import java.io.OutputStreamWriter;

import java.io.BufferedReader;

import java.io.InputStream;

/**

 * Built using CHelper plug-in

 * Actual solution is at the top

 *

 * @author mikit

 */

public class Main {

    public static void main(String[] args) {

        InputStream inputStream = System.in;

        OutputStream outputStream = System.out;

        LightScanner in = new LightScanner(inputStream);

        LightWriter out = new LightWriter(outputStream);

        C1MadhouseEasyVersion solver = new C1MadhouseEasyVersion();

        solver.solve(1, in, out);

        out.close();

    }

    static class C1MadhouseEasyVersion {

        public void solve(int testNumber, LightScanner in, LightWriter out) {

            // out.setBoolLabel(LightWriter.BoolLabel.YES_NO_FIRST_UP);

            out.enableAutoFlush();

            int m = in.ints(), n = (m + 1) / 2;

            char[] p1 = guess(in, out, 1, n);

            char[] ans = new char[m];

            if (n == 1) {

                ans[0] = p1[0];

            } else {

                char[] p2 = guess(in, out, 1, n - 1);

                int[] cnt = new int[26];

                for (int i = 0; i < n; i++) cnt[p1[i] - 'a']++;

                for (int i = 0; i < n - 1; i++) cnt[p2[i] - 'a']--;

                for (int i = 0; i < 26; i++) if (cnt[i] > 0) ans[n - 1] = (char) (i + 'a');

                for (int i = 0; i < n / 2; i++) {

                    if (ans[n - i - 1] != p1[n - i - 1]) ArrayUtil.swap(p1, i, n - i - 1);

                    ans[i] = p1[i];

                    if (ans[i] != p2[i]) ArrayUtil.swap(p2, i, n - i - 2);

                    ans[n - i - 2] = p2[n - i - 2];

                }

            }

            char[] p3 = guess(in, out, 1, m);

            for (int i = 0; i < n; i++) {

                if (p3[i] != ans[i]) ArrayUtil.swap(p3, i, m - i - 1);

            }

            out.ans('!').ans(String.valueOf(p3)).ln();

        }

        private static char[] guess(LightScanner in, LightWriter out, int from, int to) {

            int n = to - from + 1;

            if (n == 0) return new char[0];

            out.ans('?').ans(from).ans(to).ln();

            int n2 = (n + 1) / 2;

            int[][] cnt = new int[26][n + 1];

            for (int i = 0; i < n * (n + 1) / 2; i++) {

                char[] s = in.string().toCharArray();

                if (s.length < n2) continue;

                for (char c : s) cnt[c - 'a'][s.length]++;

            }

            for (int i = n2; i < n; i++) {

                for (int j = 0; j < 26; j++) {

                    cnt[j][i] -= cnt[j][i + 1];

                }

            }

            for (int i = n; i >= n2 + 1; i--) {

                for (int j = 0; j < 26; j++) {

                    cnt[j][i] -= cnt[j][i - 1];

                }

            }

            char[] ans = new char[n];

            for (int i = 0; i < n; i++) {

                int ref = Math.max(n - i, i + 1);

                for (int j = 0; j < 26; j++) {

                    if (cnt[j][ref] > 0) {

                        cnt[j][ref]--;

                        ans[i] = (char) ('a' + j);

                        break;

                    }

                }

            }

            return ans;

        }

    }

    static class LightScanner {

        private BufferedReader reader = null;

        private StringTokenizer tokenizer = null;

        public LightScanner(InputStream in) {

            reader = new BufferedReader(new InputStreamReader(in));

        }

        public String string() {

            if (tokenizer == null || !tokenizer.hasMoreTokens()) {

                try {

                    tokenizer = new StringTokenizer(reader.readLine());

                } catch (IOException e) {

                    throw new UncheckedIOException(e);

                }

            }

            return tokenizer.nextToken();

        }

        public int ints() {

            return Integer.parseInt(string());

        }

    }

    static class LightWriter implements AutoCloseable {

        private final Writer out;

        private boolean autoflush = false;

        private boolean breaked = true;

        public LightWriter(Writer out) {

            this.out = out;

        }

        public LightWriter(OutputStream out) {

            this(new OutputStreamWriter(new BufferedOutputStream(out), Charset.defaultCharset()));

        }

        public void enableAutoFlush() {

            autoflush = true;

        }

        public LightWriter print(char c) {

            try {

                out.write(c);

                breaked = false;

            } catch (IOException ex) {

                throw new UncheckedIOException(ex);

            }

            return this;

        }

        public LightWriter print(String s) {

            try {

                out.write(s, 0, s.length());

                breaked = false;

            } catch (IOException ex) {

                throw new UncheckedIOException(ex);

            }

            return this;

        }

        public LightWriter ans(char c) {

            if (!breaked) {

                print(' ');

            }

            return print(c);

        }

        public LightWriter ans(String s) {

            if (!breaked) {

                print(' ');

            }

            return print(s);

        }

        public LightWriter ans(int i) {

            return ans(Integer.toString(i));

        }

        public LightWriter ln() {

            print(System.lineSeparator());

            breaked = true;

            if (autoflush) {

                try {

                    out.flush();

                } catch (IOException ex) {

                    throw new UncheckedIOException(ex);

                }

            }

            return this;

        }

        public void close() {

            try {

                out.close();

            } catch (IOException ex) {

                throw new UncheckedIOException(ex);

            }

        }

    }

    static final class ArrayUtil {

        private ArrayUtil() {

        }

        public static void swap(char[] a, int x, int y) {

            char t = a[x];

            a[x] = a[y];

            a[y] = t;

        }

    }

}