Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.*;
- import java.util.Arrays;
- import java.util.Comparator;
- import java.util.StringTokenizer;
- public class SolSqrt {
- FastScanner in;
- PrintWriter out;
- class Cell {
- long currentStart;
- long atLeast;
- int pos;
- public Cell(long currentStart, long atLeast, int pos) {
- this.currentStart = currentStart;
- this.atLeast = atLeast;
- this.pos = pos;
- }
- public long getValue(long currentAdd) {
- return Math.max(atLeast, currentStart + currentAdd);
- }
- }
- long whenSecondSmaller(Cell c1, Cell c2) {
- if (c2.currentStart >= c1.currentStart) {
- return Long.MAX_VALUE;
- }
- return c2.atLeast - c1.currentStart;
- }
- class Block {
- int l, r;
- long currentAdd;
- Cell[] cells;
- Cell[] stack;
- int stackSize;
- void buildStack() {
- System.arraycopy(cells, 0, stack, 0, cells.length);
- Arrays.sort(stack, new Comparator<Cell>() {
- @Override
- public int compare(Cell o1, Cell o2) {
- return Long.compare(o1.atLeast, o2.atLeast);
- }
- });
- stackSize = 1;
- for (int i = 1; i < cells.length; i++) {
- Cell last = stack[stackSize - 1];
- Cell newOne = stack[i];
- long t1 = whenSecondSmaller(last, newOne);
- if (t1 == Long.MAX_VALUE) {
- continue;
- }
- while (stackSize >= 2) {
- Cell p2 = stack[stackSize - 2];
- Cell p1 = stack[stackSize - 1];
- long tP1P2 = whenSecondSmaller(p2, p1);
- long myT = whenSecondSmaller(p1, newOne);
- if (myT <= tP1P2) {
- stackSize--;
- } else {
- break;
- }
- }
- stack[stackSize++] = newOne;
- }
- }
- long getMinInStack() {
- if (stackSize == 1 || whenSecondSmaller(stack[0], stack[1]) >= currentAdd) {
- return stack[0].getValue(currentAdd);
- }
- int l = 0, r = stackSize - 1;
- while (r - l > 1) {
- int m = (l + r) >> 1;
- Cell c1 = stack[m], c2 = stack[m + 1];
- long t = whenSecondSmaller(c1, c2);
- if (t > currentAdd) {
- r = m;
- } else {
- l = m;
- }
- }
- return stack[r].getValue(currentAdd);
- }
- long getMin(int lQuery, int rQuery) {
- if (lQuery > r || rQuery < l) {
- return Long.MAX_VALUE;
- }
- if (lQuery <= l && rQuery >= r) {
- return getMinInStack();
- }
- long min = Long.MAX_VALUE;
- for (Cell c : cells) {
- if (c.pos >= lQuery && c.pos <= rQuery) {
- min = Math.min(min, c.getValue(currentAdd));
- }
- }
- return min;
- }
- void add(int lQuery, int rQuery, long delta) {
- if (lQuery > r || rQuery < l) {
- return;
- }
- if (lQuery <= l && rQuery >= r) {
- currentAdd += delta;
- return;
- }
- for (Cell c : cells) {
- if (c.pos >= lQuery && c.pos <= rQuery) {
- c.currentStart += delta;
- }
- }
- buildStack();
- }
- Block(long[] currentStart, long[] atLeast, int l, int r) {
- this.l = l;
- this.r = r;
- cells = new Cell[r - l + 1];
- for (int i = 0; i < cells.length; i++) {
- int pos = l + i;
- cells[i] = new Cell(currentStart[pos], atLeast[pos], pos);
- }
- stack = new Cell[cells.length];
- buildStack();
- }
- }
- void solve() {
- int n = in.nextInt();
- int q = in.nextInt();
- long[] expected = new long[n];
- long[] current = new long[n];
- for (int i = 0; i < n; i++) {
- current[i] = in.nextLong();
- expected[i] = in.nextLong();
- }
- final int SQRT = 150;
- Block[] blocks = new Block[(n + SQRT - 1) / SQRT];
- for (int i = 0; i < blocks.length; i++) {
- int from = i * SQRT;
- int to = Math.min(n, (i + 1) * SQRT) - 1;
- blocks[i] = new Block(current, expected, from, to);
- }
- for (int i = 0; i < q; i++) {
- if (in.nextInt() == 1) {
- int left = in.nextInt() - 1, right = in.nextInt() - 1;
- int delta = in.nextInt();
- for (Block b : blocks) {
- b.add(left, right, delta);
- }
- } else {
- int left = in.nextInt() - 1, right = in.nextInt() - 1;
- long min = Long.MAX_VALUE;
- for (Block b : blocks) {
- min = Math.min(b.getMin(left, right), min);
- }
- out.println(min);
- }
- }
- }
- void run() {
- try {
- in = new FastScanner(new File("Sol.in"));
- out = new PrintWriter(new File("Sol.out"));
- solve();
- out.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
- void runIO() {
- in = new FastScanner(System.in);
- out = new PrintWriter(System.out);
- solve();
- out.close();
- }
- class FastScanner {
- BufferedReader br;
- StringTokenizer st;
- public FastScanner(File f) {
- try {
- br = new BufferedReader(new FileReader(f));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
- public FastScanner(InputStream f) {
- br = new BufferedReader(new InputStreamReader(f));
- }
- String next() {
- while (st == null || !st.hasMoreTokens()) {
- String s = null;
- try {
- s = br.readLine();
- } catch (IOException e) {
- e.printStackTrace();
- }
- if (s == null)
- return null;
- st = new StringTokenizer(s);
- }
- return st.nextToken();
- }
- boolean hasMoreTokens() {
- while (st == null || !st.hasMoreTokens()) {
- String s = null;
- try {
- s = br.readLine();
- } catch (IOException e) {
- e.printStackTrace();
- }
- if (s == null)
- return false;
- st = new StringTokenizer(s);
- }
- return true;
- }
- int nextInt() {
- return Integer.parseInt(next());
- }
- long nextLong() {
- return Long.parseLong(next());
- }
- double nextDouble() {
- return Double.parseDouble(next());
- }
- }
- public static void main(String[] args) {
- new SolSqrt().runIO();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment