gt22 icon

Untitled

gt22 | PRO | 09/13/18 04:57:11 PM UTC | 0 ⭐ | 925 👁️ | Never ⏰ | []
Java |

2.47 KB

|

None

|

0 👍

/

0 👎

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
 
public class O1112_sparsetable {
 
 
    public static void main(String[] args) throws IOException {
        BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
        int M = Integer.parseInt(r.readLine());
        List<Integer> data = new ArrayList<>();
        String s;
        while(!(s = r.readLine()).equals("-1")) {
            data.add(Integer.parseInt(s));
        }
        int[] d = new int[data.size()];
        for (int i = 0; i < data.size(); i++) {
            d[i] = data.get(i);
        }
        SparseTable table = new SparseTable(d);
        for (int i = 0; i <= data.size() - M; i++) {
            System.out.println(table.calc(i, i + M - 1));
        }
    }
 
 
    static class SparseTable {
 
        final int[][] data;
        final int[] lenToPOT;
        final int size;
        final int maxPOT;
 
        SparseTable(int size) {
            data = new int[maxPOT = getPOT(size) + 1][this.size = size];
            lenToPOT = new int[size + 1];
            for (int i = 1; i <= size; i++) {
                lenToPOT[i] = getPOT(i);
            }
        }
 
        SparseTable(int[] orig) {
            this(orig.length);
            init(orig);
        }
 
        private void init(int[] orig) {
            System.arraycopy(orig, 0, data[0], 0, orig.length);
            for (int i = 1; i <= maxPOT; i++) {
                int len = 1 << i;
                int end = size - len + 1;
                for (int j = 0; j < end; j++) {
                    int left = data[i - 1][j];
                    int right = data[i - 1][j + (len / 2)];
                    data[i][j] = Math.max(left, right);
                }
            }
        }
 
 
        int calc(int from, int to) {
            int pot = lenToPOT[to - from + 1];
            int[] locData = data[pot];
            int len = 1 << pot;
            int left = locData[from];
            int right = locData[to - len + 1];
            return Math.max(left, right);
        }
 
 
        private int getPOT(int num) {
            if(num == 1) return 0;
 
            int pot = 0;
            int i = 1;
            while(true) {
                i *= 2;
                if(i >= num) {
                    return pot;
                }
                pot++;
            }
        }
 
    }
 
 
 
}

Comments