結果

問題 No.619 CardShuffle
ユーザー 👑 hos.lyric
提出日時 2019-01-21 07:44:57
言語 D
(dmd 2.109.1)
結果
AC  
実行時間 217 ms / 3,000 ms
コード長 5,250 bytes
コンパイル時間 1,875 ms
コンパイル使用メモリ 163,456 KB
実行使用メモリ 19,168 KB
最終ジャッジ日時 2024-06-13 03:24:56
合計ジャッジ時間 7,054 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other AC * 35
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

import std.conv, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.container, std.math, std.numeric, std.range, std.regex, std.typecons;
import core.bitop;
class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens
    .popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }
void chmin(T)(ref T t, in T f) { if (t > f) t = f; }
void chmax(T)(ref T t, in T f) { if (t < f) t = f; }
int binarySearch(T)(in T[] as, in bool delegate(T) test) { int low = -1, upp = cast(int)(as.length); for (; low + 1 < upp; ) { int mid = (low + upp)
    >> 1; (test(as[mid]) ? low : upp) = mid; } return upp; }
int lowerBound(T)(in T[] as, in T val) { return as.binarySearch((T a) => (a < val)); }
int upperBound(T)(in T[] as, in T val) { return as.binarySearch((T a) => (a <= val)); }
enum MO = 10L^^9 + 7;
class SegmentTree(string Op) if (Op == "+" || Op == "*") {
int n;
long[] prod;
this(long[] ini) {
for (n = 1; n < ini.length; n <<= 1) {}
prod = new long[n << 1];
foreach (i, val; ini) {
prod[n + i] = val;
}
foreach_reverse (a; 1 .. n) {
prod[a] = mixin(`(prod[a << 1] ` ~ Op ~ ` prod[a << 1 | 1]) % MO`);
}
}
void update(int a, long val) {
prod[a += n] = val;
for (a >>= 1; a; a >>= 1) {
prod[a] = mixin(`(prod[a << 1] ` ~ Op ~ ` prod[a << 1 | 1]) % MO`);
}
}
long rangeProd(int a, int b) {
long ret = (Op == "+") ? 0 : 1;
for (a += n, b += n; a <= b; a >>= 1, b >>= 1) {
if ( a & 1) mixin(`(ret ` ~ Op ~ `= prod[a++]) %= MO;`);
if (~b & 1) mixin(`(ret ` ~ Op ~ `= prod[b--]) %= MO;`);
}
return ret;
}
}
/*
C: 0 1 2 3
O: 0 1 2 3 4
*/
int N;
long[] C;
string[] O;
int Q;
string[] T;
int[] X, Y;
void main() {
try {
for (; ; ) {
N = readInt() / 2 + 1;
C = new long[N];
O = new string[N + 1];
C[0] = readLong();
foreach (i; 1 .. N) {
O[i] = readToken();
C[i] = readLong();
}
O[0] = O[N] = "+";
Q = readInt();
T = new string[Q];
X = new int[Q];
Y = new int[Q];
foreach (q; 0 .. Q) {
T[q] = readToken();
X[q] = readInt();
Y[q] = readInt();
}
auto segProd = new SegmentTree!"*"(C);
auto sums = new long[N];
auto pluses = new RedBlackTree!int();
int bef = -1;
foreach (i; 0 .. N + 1) {
if (O[i] == "+") {
pluses.insert(i);
if (bef != -1) {
sums[bef] = segProd.rangeProd(bef, i - 1);
}
bef = i;
}
}
auto segSum = new SegmentTree!"+"(sums);
debug {
writeln("sums = ", sums);
}
void updateC(int i) {
debug {
writeln("updateC ", i);
}
segProd.update(i, C[i]);
const lb = pluses.lowerBound(i + 1).back;
const ub = pluses.upperBound(i).front;
sums[lb] = segProd.rangeProd(lb, ub - 1);
segSum.update(lb, sums[lb]);
}
void updateOp(int i) {
debug {
writeln("updateOp ", i, " ", O[i]);
}
const lb = pluses.lowerBound(i).back;
const ub = pluses.upperBound(i).front;
switch (O[i]) {
case "+": {
// "*" -> "+"
pluses.insert(i);
sums[lb] = segProd.rangeProd(lb, i - 1);
sums[i] = segProd.rangeProd(i, ub - 1);
} break;
case "*": {
// "+" -> "*"
pluses.removeKey(i);
sums[lb] = segProd.rangeProd(lb, ub - 1);
sums[i] = 0;
} break;
default: assert(false);
}
segSum.update(lb, sums[lb]);
segSum.update(i, sums[i]);
}
foreach (q; 0 .. Q) {
switch (T[q]) {
case "!": {
if (X[q] % 2 == 0) {
if (O[X[q] / 2] != O[Y[q] / 2]) {
swap(O[X[q] / 2], O[Y[q] / 2]);
updateOp(X[q] / 2);
updateOp(Y[q] / 2);
}
} else {
swap(C[X[q] / 2], C[Y[q] / 2]);
updateC(X[q] / 2);
updateC(Y[q] / 2);
}
} break;
case "?": {
const l = pluses.upperBound(X[q] / 2).front;
const r = pluses.lowerBound(Y[q] / 2 + 1).back;
debug {
writeln("? ", X[q] / 2, " ", Y[q] / 2);
writeln(" l = ", l, ", r = ", r);
}
long ans;
if (l <= r) {
ans += segProd.rangeProd(X[q] / 2, l - 1);
ans += segSum.rangeProd(l, r - 1);
ans += segProd.rangeProd(r, Y[q] / 2);
} else {
ans += segProd.rangeProd(X[q] / 2, Y[q] / 2);
}
ans %= MO;
writeln(ans);
} break;
default: assert(false);
}
debug {
writeln("C = ", C);
writeln("pluses = ", pluses);
}
}
}
} catch (EOFException e) {
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0