結果
| 問題 |
No.1234 典型RMQ
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-10-05 14:55:43 |
| 言語 | Java (openjdk 23) |
| 結果 |
AC
|
| 実行時間 | 1,489 ms / 2,000 ms |
| コード長 | 8,175 bytes |
| コンパイル時間 | 3,826 ms |
| コンパイル使用メモリ | 93,916 KB |
| 実行使用メモリ | 144,912 KB |
| 最終ジャッジ日時 | 2025-10-05 14:57:18 |
| 合計ジャッジ時間 | 28,883 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 27 |
ソースコード
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.function.IntFunction;
import java.util.stream.IntStream;
import java.util.stream.Stream;
class FastScanner {
private static FastScanner instance = null;
private final InputStream in = System.in;
private final byte[] buffer = new byte[1024];
private int ptr = 0;
private int buflen = 0;
// 外部から new できないようにする
private FastScanner() {
}
public static FastScanner getInstance() {
if (instance == null) {
instance = new FastScanner();
}
return instance;
}
private boolean hasNextByte() {
if (ptr < buflen) {
return true;
}
ptr = 0;
try {
buflen = in.read(buffer);
} catch (IOException e) {
e.printStackTrace();
}
return buflen > 0;
}
private int readByte() {
if (hasNextByte()) {
return buffer[ptr++];
} else {
return -1;
}
}
private boolean isPrintableChar(int c) {
return (33 <= c) && (c <= 126);
}
public boolean hasNext() {
while (hasNextByte() && (!isPrintableChar(buffer[ptr]))) {
ptr++;
}
return hasNextByte();
}
public long nextLong() {
if (!hasNext()) {
throw new NoSuchElementException();
}
long n = 0;
boolean minus = false;
int b = readByte();
if (b == '-') {
minus = true;
b = readByte();
}
while ((b >= '0') && (b <= '9')) {
n = (n * 10) + (b - '0');
b = readByte();
}
return minus ? -n : n;
}
public int nextInt() {
return ((int) (nextLong()));
}
public long[] nextLongs(int n) {
long[] a = new long[n];
for (int i = 0; i < n; ++i) {
a[i] = nextLong();
}
return a;
}
}
abstract class MonoidAction<A extends Monoid<?>, X extends Monoid<?>> {
public X merge(A a, X b) {
if (a == null) {
return b;
}
return mergeNonNull(a, b);
}
protected abstract X mergeNonNull(A a, X b);
}
/**
* null は identity の代わり
*/
class LazySegTree<ActingMonoid extends Monoid<ActingMonoid>, ActedMonoid extends Monoid<ActedMonoid>> {
int n = 1;
ActedMonoid[] v;
ActingMonoid[] lazy;
private MonoidAction<ActingMonoid, ActedMonoid> ma;
Object identity = null;
@SuppressWarnings("unchecked")
public LazySegTree(int n, MonoidAction<ActingMonoid, ActedMonoid> ma) {
this.n = 2 * Integer.highestOneBit(n);
v = ((ActedMonoid[]) (new Monoid[this.n * 2]));
lazy = ((ActingMonoid[]) (new Monoid[this.n * 2]));
this.ma = ma;
}
@SuppressWarnings("unchecked")
public void build(ActedMonoid[] arr) {
for (int i = 0; i < arr.length; ++i) {
v[id(i, i + 1)] = arr[i];
}
for (int i = id(0, 1) - 1; i >= id(0, n); --i) {
v[i] = merge(v[2 * i], v[(2 * i) + 1]);
}
}
private void push(int k) {
if (lazy[k] == identity) {
return;
}
v[k] = ma.merge(((ActingMonoid) (lazy[k])), ((ActedMonoid) (v[k])));
if (((2 * k) + 1) < v.length) {
lazy[2 * k] = mergeLazy(lazy[k], lazy[2 * k]);
lazy[(2 * k) + 1] = mergeLazy(lazy[k], lazy[(2 * k) + 1]);
}
lazy[k] = null;
}
public ActedMonoid query(int a, int b) {
return query(a, b, null);
}
public ActedMonoid query(int a, int b, ActingMonoid add) {
return query(0, n, a, b, 1, add);
}
private ActedMonoid query(int l, int r, int a, int b, int k, ActingMonoid add) {
if (((a <= l) && (r <= b)) && (add != null)) {
lazy[k] = mergeLazy(add, lazy[k]);
}
push(k);
if ((a <= l) && (r <= b)) {
return ((ActedMonoid) (v[k]));
} else if ((r <= a) || (b <= l)) {
return null;
} else {
int m = (l + r) / 2;
ActedMonoid vl = query(l, m, a, b, 2 * k, add);
ActedMonoid vr = query(m, r, a, b, (2 * k) + 1, add);
v[k] = merge(v[2 * k], v[(2 * k) + 1]);
return merge(vl, vr);
}
}
private ActedMonoid merge(ActedMonoid a, ActedMonoid b) {
if (a == identity) {
return b;
}
if (b == identity) {
return a;
}
return a.merge(b);
}
private ActingMonoid mergeLazy(ActingMonoid a, ActingMonoid b) {
if (a == identity) {
return b;
}
if (b == identity) {
return a;
}
return a.merge(b);
}
int id(int a, int b) {
int w = Integer.lowestOneBit(a ^ b);
return (n / w) + (a / w);
}
}
class AddArgMin<T extends Comparable<T>> extends MonoidAction<AddMonoid<T>, ArgMinMonoid<T>> {
@Override
protected ArgMinMonoid<T> mergeNonNull(AddMonoid<T> a, ArgMinMonoid<T> b) {
return new ArgMinMonoid<>(b.pos, AddMonoid.add(a.val, b.val));
}
}
class ArgMinMonoid<T extends Comparable<T>> extends Monoid<ArgMinMonoid<T>> {
public int pos;
public T val;
public ArgMinMonoid(int pos, T val) {
this.pos = pos;
this.val = val;
}
@Override
public ArgMinMonoid<T> merge(ArgMinMonoid<T> a) {
return val.compareTo(a.val) <= 0 ? this : a;
}
}
class AddMonoid<T> extends Monoid<AddMonoid<T>> {
final T val;
public AddMonoid(T val) {
this.val = val;
}
@SuppressWarnings("unchecked")
@Override
public AddMonoid<T> merge(AddMonoid<T> a) {
return new AddMonoid<>(add(val, a.val));
}
@SuppressWarnings("unchecked")
public static <T> T add(T a, T b) {
if ((a instanceof Integer av) && (b instanceof Integer bv)) {
return ((T) (Integer.valueOf(av + bv)));
} else if ((a instanceof Long av) && (b instanceof Long bv)) {
return ((T) (Long.valueOf(av + bv)));
} else if ((a instanceof Double av) && (b instanceof Double bv)) {
return ((T) (Double.valueOf(av + bv)));
} else if ((a instanceof Float av) && (b instanceof Float bv)) {
return ((T) (Float.valueOf(av + bv)));
} else {
throw new UnsupportedOperationException("Unsupported numeric type: " + a.getClass());
}
}
}
abstract class Monoid<X> {
public abstract X merge(X a);
}
class MyPrintWriter extends PrintWriter {
private static MyPrintWriter instance = null;
private MyPrintWriter() {
super(System.out);
}
public static MyPrintWriter getInstance() {
if (instance == null) {
instance = new MyPrintWriter();
}
return instance;
}
}
public class Main implements Runnable {
public static void main(String[] args) throws IOException {
new Thread(null, new Main(), "", (1024 * 1024) * 1024).start();// 1024MBスタックを確保して実行
}
@Override
public void run() {
FastScanner sc = FastScanner.getInstance();
MyPrintWriter pw = MyPrintWriter.getInstance();
int N = sc.nextInt();
long[] A = sc.nextLongs(N);
int Q = sc.nextInt();
var tree = new LazySegTree<>(N, new AddArgMin<Long>());
tree.build(IntStream.range(0, N).mapToObj(i -> new ArgMinMonoid<>(i, A[i])).toArray(ArgMinMonoid[]::new));
for (int i = 0; i < Q; i++) {
int type = sc.nextInt();
int s = sc.nextInt() - 1;
int t = sc.nextInt() - 1;
long c = sc.nextLong();
t++;
if (type == 1) {
tree.query(s, t, new AddMonoid<Long>(((long) (c))));
} else {
pw.println(tree.query(s, t).val);
}
}
pw.close();
}
}