Advertisement
IzhanVarsky

RMQ наоборот

Mar 19th, 2019
407
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.40 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4. public class Main {
  5.  
  6.     public static class MyList implements Comparable<MyList> {
  7.         private int left;
  8.         private int right;
  9.         private int value;
  10.  
  11.         MyList(int left, int right, int value) {
  12.             this.left = left;
  13.             this.right = right;
  14.             this.value = value;
  15.         }
  16.  
  17.         int getLeft() {
  18.             return left;
  19.         }
  20.  
  21.         int getRight() {
  22.             return right;
  23.         }
  24.  
  25.         int getValue() {
  26.             return value;
  27.         }
  28.  
  29.         @Override
  30.         public int compareTo(MyList list) {
  31.             if (this.left == list.left) {
  32.                 if (this.value == list.value) return this.right - list.left;
  33.                 return -this.value + list.value;
  34.             }
  35.             return this.left - list.left;
  36.         }
  37.     }
  38.  
  39.     private static int[] t;
  40.     private static int value;
  41.     private static boolean canHasAns = true;
  42.  
  43.     private static void useMin(int v, int left, int right, int a, int b) {
  44.         if (a > right || b < left) return;
  45.         if (a == left && b == right) {
  46.             if (t[v] > value && t[v] != Integer.MAX_VALUE) {
  47. //                canHasAns = false;
  48.                 return;
  49.             }
  50.             t[v] = value;
  51.             return;
  52.         }
  53.         int mid = (left + right) / 2;
  54.         useMin(v * 2 + 1, left, mid, a, Math.min(b, mid));
  55.         useMin(v * 2 + 2, mid + 1, right, Math.max(a, mid + 1), b);
  56.     }
  57.  
  58.     private static void pushMin(int v) {
  59.         if (v * 2 + 2 < t.length) {
  60.             int v_left = v * 2 + 1;
  61.             t[v_left] = value;
  62.             v_left++; // стал v_right
  63.             t[v_left] = value;
  64.         }
  65.     }
  66.  
  67.     private static void setMin(int i) {
  68.         t[i] = Math.min(t[i * 2 + 1], t[i * 2 + 2]);
  69.     }
  70.  
  71.     public static void main(String[] args) {
  72.         try (Scanner in = new Scanner(new FileReader("rmq.in")); BufferedWriter writer = new BufferedWriter(new FileWriter("rmq.out"))) {
  73. //        Scanner in = new Scanner(System.in);
  74.             // БЛОК 1
  75.             int n = in.nextInt();
  76.             int m = in.nextInt();
  77.             MyList megaList[] = new MyList[m];
  78.             for (int i = 0; i < m; i++)
  79.                 megaList[i] = new MyList(in.nextInt() - 1, in.nextInt() - 1, in.nextInt());
  80. //            Arrays.sort(megaList);
  81.  
  82.             // БЛОК 2
  83.             // пытаемся построить на ДО
  84.             int newN = getNewN(n);
  85.             t = new int[newN * 2 - 1];
  86.             for (int i = 0; i < newN * 2 - 1; i++)
  87.                 t[i] = Integer.MAX_VALUE;
  88.             for (int i = 0; i < m; i++) {
  89.                 int mainLeft = megaList[i].getLeft();
  90.                 int mainRight = megaList[i].getRight();
  91.                 value = megaList[i].getValue();
  92.                 useMin(0, 0, newN - 1, mainLeft, mainRight);
  93.                 if (!canHasAns) {
  94.                     System.out.println("inconsistent");
  95.                     return;
  96.                 }
  97.             }
  98.  
  99.             // посчитать res
  100.             pushUntilLeave(0);
  101.             int[] res = new int[n];
  102.             for (int i = 0; i < n; i++) {
  103.                 res[i] = t[newN - 1 + i];
  104.             }
  105.             System.out.println(Arrays.toString(res));
  106.  
  107.             // БЛОК 3
  108.             // check on segment tree:
  109.             t = new int[newN * 2 - 1];
  110.             // build
  111.             for (int i = 0; i < newN * 2 - 1; i++)
  112.                 t[i] = Integer.MAX_VALUE;
  113.             System.arraycopy(res, 0, t, newN - 1, n);
  114.             for (int i = newN - 2; i >= 0; i--)
  115.                 setMin(i);
  116.             //
  117.             for (MyList i : megaList) {
  118.                 int left = i.getLeft();
  119.                 int right = i.getRight();
  120.                 int value = i.getValue();
  121.                 int k = getMin(0, 0, newN - 1, left, right);
  122.                 if (value != k) {
  123.                     writer.write("inconsistent");
  124.                     System.out.println("inconsistent");
  125.                     return;
  126.                 }
  127.             }
  128.             writer.write("consistent" + '\n');
  129.             System.out.println("consistent" + '\n');
  130.             for (int i = 0; i < n; i++) {
  131.                 writer.write(res[i] + " ");
  132.             }
  133.         } catch (IOException e) {
  134.             e.printStackTrace();
  135.         }
  136.     }
  137.  
  138.     private static void pushUntilLeave(int v) {
  139.         if (v * 2 + 2 < t.length) {
  140.             int v_left = v * 2 + 1;
  141.             if (t[v_left] == Integer.MAX_VALUE || t[v_left] < t[v] && t[v] != Integer.MAX_VALUE)
  142.                 t[v_left] = t[v];
  143.             pushUntilLeave(v_left);
  144.             v_left++; // стал v_right
  145.             if (t[v_left] == Integer.MAX_VALUE || t[v_left] < t[v] && t[v] != Integer.MAX_VALUE)
  146.                 t[v_left] = t[v];
  147.             pushUntilLeave(v_left);
  148.         }
  149.     }
  150.  
  151.     private static int getMin(int v, int left, int right, int a, int b) {
  152.         if (a > right || b < left) return Integer.MAX_VALUE;
  153.         if (a == left && b == right) return t[v];
  154.         int mid = (left + right) / 2;
  155.         return Math.min(getMin(v * 2 + 1, left, mid, a, Math.min(b, mid)),
  156.                 getMin(v * 2 + 2, mid + 1, right, Math.max(a, mid + 1), b));
  157.     }
  158.  
  159.     private static int getNewN(int n) {
  160.         int res = 1;
  161.         while (res < n)
  162.             res <<= 1;
  163.         return res;
  164.     }
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement