qwerty787788

SQRT

Aug 21st, 2020
1,180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.42 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.Arrays;
  3. import java.util.Comparator;
  4. import java.util.StringTokenizer;
  5.  
  6. public class SolSqrt {
  7.     FastScanner in;
  8.     PrintWriter out;
  9.  
  10.     class Cell {
  11.         long currentStart;
  12.         long atLeast;
  13.         int pos;
  14.  
  15.         public Cell(long currentStart, long atLeast, int pos) {
  16.             this.currentStart = currentStart;
  17.             this.atLeast = atLeast;
  18.             this.pos = pos;
  19.         }
  20.  
  21.         public long getValue(long currentAdd) {
  22.             return Math.max(atLeast, currentStart + currentAdd);
  23.         }
  24.     }
  25.  
  26.     long whenSecondSmaller(Cell c1, Cell c2) {
  27.         if (c2.currentStart >= c1.currentStart) {
  28.             return Long.MAX_VALUE;
  29.         }
  30.         return c2.atLeast - c1.currentStart;
  31.     }
  32.  
  33.     class Block {
  34.         int l, r;
  35.         long currentAdd;
  36.         Cell[] cells;
  37.         Cell[] stack;
  38.         int stackSize;
  39.  
  40.         void buildStack() {
  41.             System.arraycopy(cells, 0, stack, 0, cells.length);
  42.             Arrays.sort(stack, new Comparator<Cell>() {
  43.                 @Override
  44.                 public int compare(Cell o1, Cell o2) {
  45.                     return Long.compare(o1.atLeast, o2.atLeast);
  46.                 }
  47.             });
  48.             stackSize = 1;
  49.             for (int i = 1; i < cells.length; i++) {
  50.                 Cell last = stack[stackSize - 1];
  51.                 Cell newOne = stack[i];
  52.                 long t1 = whenSecondSmaller(last, newOne);
  53.                 if (t1 == Long.MAX_VALUE) {
  54.                     continue;
  55.                 }
  56.                 while (stackSize >= 2) {
  57.                     Cell p2 = stack[stackSize - 2];
  58.                     Cell p1 = stack[stackSize - 1];
  59.                     long tP1P2 = whenSecondSmaller(p2, p1);
  60.                     long myT = whenSecondSmaller(p1, newOne);
  61.                     if (myT <= tP1P2) {
  62.                         stackSize--;
  63.                     } else {
  64.                         break;
  65.                     }
  66.                 }
  67.                 stack[stackSize++] = newOne;
  68.             }
  69.         }
  70.  
  71.         long getMinInStack() {
  72.             if (stackSize == 1 || whenSecondSmaller(stack[0], stack[1]) >= currentAdd) {
  73.                 return stack[0].getValue(currentAdd);
  74.             }
  75.             int l = 0, r = stackSize - 1;
  76.             while (r - l > 1) {
  77.                 int m = (l + r) >> 1;
  78.                 Cell c1 = stack[m], c2 = stack[m + 1];
  79.                 long t = whenSecondSmaller(c1, c2);
  80.                 if (t > currentAdd) {
  81.                     r = m;
  82.                 } else {
  83.                     l = m;
  84.                 }
  85.             }
  86.             return stack[r].getValue(currentAdd);
  87.         }
  88.  
  89.         long getMin(int lQuery, int rQuery) {
  90.             if (lQuery > r || rQuery < l) {
  91.                 return Long.MAX_VALUE;
  92.             }
  93.             if (lQuery <= l && rQuery >= r) {
  94.                 return getMinInStack();
  95.             }
  96.             long min = Long.MAX_VALUE;
  97.             for (Cell c : cells) {
  98.                 if (c.pos >= lQuery && c.pos <= rQuery) {
  99.                     min = Math.min(min, c.getValue(currentAdd));
  100.                 }
  101.             }
  102.             return min;
  103.         }
  104.  
  105.         void add(int lQuery, int rQuery, long delta) {
  106.             if (lQuery > r || rQuery < l) {
  107.                 return;
  108.             }
  109.             if (lQuery <= l && rQuery >= r) {
  110.                 currentAdd += delta;
  111.                 return;
  112.             }
  113.             for (Cell c : cells) {
  114.                 if (c.pos >= lQuery && c.pos <= rQuery) {
  115.                     c.currentStart += delta;
  116.                 }
  117.             }
  118.             buildStack();
  119.         }
  120.  
  121.         Block(long[] currentStart, long[] atLeast, int l, int r) {
  122.             this.l = l;
  123.             this.r = r;
  124.             cells = new Cell[r - l + 1];
  125.             for (int i = 0; i < cells.length; i++) {
  126.                 int pos = l + i;
  127.                 cells[i] = new Cell(currentStart[pos], atLeast[pos], pos);
  128.             }
  129.             stack = new Cell[cells.length];
  130.             buildStack();
  131.         }
  132.  
  133.     }
  134.  
  135.     void solve() {
  136.         int n = in.nextInt();
  137.         int q = in.nextInt();
  138.         long[] expected = new long[n];
  139.         long[] current = new long[n];
  140.         for (int i = 0; i < n; i++) {
  141.             current[i] = in.nextLong();
  142.             expected[i] = in.nextLong();
  143.         }
  144.         final int SQRT = 150;
  145.         Block[] blocks = new Block[(n + SQRT - 1) / SQRT];
  146.         for (int i = 0; i < blocks.length; i++) {
  147.             int from = i * SQRT;
  148.             int to = Math.min(n, (i + 1) * SQRT) - 1;
  149.             blocks[i] = new Block(current, expected, from, to);
  150.         }
  151.         for (int i = 0; i < q; i++) {
  152.             if (in.nextInt() == 1) {
  153.                 int left = in.nextInt() - 1, right = in.nextInt() - 1;
  154.                 int delta = in.nextInt();
  155.                 for (Block b : blocks) {
  156.                     b.add(left, right, delta);
  157.                 }
  158.             } else {
  159.                 int left = in.nextInt() - 1, right = in.nextInt() - 1;
  160.                 long min = Long.MAX_VALUE;
  161.                 for (Block b : blocks) {
  162.                     min = Math.min(b.getMin(left, right), min);
  163.                 }
  164.                 out.println(min);
  165.             }
  166.         }
  167.     }
  168.  
  169.     void run() {
  170.         try {
  171.             in = new FastScanner(new File("Sol.in"));
  172.             out = new PrintWriter(new File("Sol.out"));
  173.  
  174.             solve();
  175.  
  176.             out.close();
  177.         } catch (FileNotFoundException e) {
  178.             e.printStackTrace();
  179.         }
  180.     }
  181.  
  182.     void runIO() {
  183.  
  184.         in = new FastScanner(System.in);
  185.         out = new PrintWriter(System.out);
  186.  
  187.         solve();
  188.  
  189.         out.close();
  190.     }
  191.  
  192.     class FastScanner {
  193.         BufferedReader br;
  194.         StringTokenizer st;
  195.  
  196.         public FastScanner(File f) {
  197.             try {
  198.                 br = new BufferedReader(new FileReader(f));
  199.             } catch (FileNotFoundException e) {
  200.                 e.printStackTrace();
  201.             }
  202.         }
  203.  
  204.         public FastScanner(InputStream f) {
  205.             br = new BufferedReader(new InputStreamReader(f));
  206.         }
  207.  
  208.         String next() {
  209.             while (st == null || !st.hasMoreTokens()) {
  210.                 String s = null;
  211.                 try {
  212.                     s = br.readLine();
  213.                 } catch (IOException e) {
  214.                     e.printStackTrace();
  215.                 }
  216.                 if (s == null)
  217.                     return null;
  218.                 st = new StringTokenizer(s);
  219.             }
  220.             return st.nextToken();
  221.         }
  222.  
  223.         boolean hasMoreTokens() {
  224.             while (st == null || !st.hasMoreTokens()) {
  225.                 String s = null;
  226.                 try {
  227.                     s = br.readLine();
  228.                 } catch (IOException e) {
  229.                     e.printStackTrace();
  230.                 }
  231.                 if (s == null)
  232.                     return false;
  233.                 st = new StringTokenizer(s);
  234.             }
  235.             return true;
  236.         }
  237.  
  238.         int nextInt() {
  239.             return Integer.parseInt(next());
  240.         }
  241.  
  242.         long nextLong() {
  243.             return Long.parseLong(next());
  244.         }
  245.  
  246.         double nextDouble() {
  247.             return Double.parseDouble(next());
  248.         }
  249.     }
  250.  
  251.     public static void main(String[] args) {
  252.         new SolSqrt().runIO();
  253.     }
  254. }
Advertisement
Add Comment
Please, Sign In to add comment