29
StackTransform::StackTransform(std::initializer_list<int> list) {
33
StackTransform &StackTransform::operator=(std::initializer_list<int> list) {
34
if (list.size() > 255) {
42
int m = (int)list.size();
43
d = list.begin()[m - 1] - (m - 1);
44
if (d >= 128 || d < -128) {
48
for (int i = 0; i < m - 1; i++) {
50
int y = list.begin()[i];
52
if (x != (short)x || y != (short)y || n == max_n) {
56
dp = std::max(dp, std::max(x, y) + 1);
57
A[n++] = std::make_pair((short)x, (short)y);
63
bool StackTransform::assign(const StackTransform &other) {
64
if (!other.is_valid() || (unsigned)other.n > max_n) {
72
for (int i = 0; i < n; i++) {
78
int StackTransform::get(int x) const {
87
for (i = 0; i < n && A[i].first < x; i++) {
89
if (i < n && A[i].first == x) {
96
bool StackTransform::set(int x, int y, bool relaxed) {
101
return (relaxed && y == x + d) || invalidate();
108
for (i = 0; i < n && A[i].first < x; i++) {
110
if (i < n && A[i].first == x) {
115
A[i].second = (short)y;
124
if (x != (short)x || y != (short)y || n == max_n) {
127
for (int j = n++; j > i; j--) {
130
A[i].first = (short)x;
131
A[i].second = (short)y;
140
bool StackTransform::is_trivial_after(int x) const {
141
return is_valid() && (!n || A[n - 1].first < x + d);
145
int StackTransform::preimage_count(int y) const {
149
int count = (y >= d);
150
for (const auto &pair : A) {
151
if (pair.second == y) {
153
} else if (pair.first == y) {
161
std::vector<int> StackTransform::preimage(int y) const {
165
std::vector<int> res;
167
for (const auto &pair : A) {
168
if (pair.first > y && f) {
169
res.push_back(y - d);
172
if (pair.first == y) {
174
} else if (pair.second == y) {
175
res.push_back(pair.first - d);
182
bool StackTransform::is_permutation() const {
183
if (!is_valid() || d) {
186
func_assert(n <= max_n);
187
std::array<int, max_n> X, Y;
188
for (int i = 0; i < n; i++) {
195
std::sort(Y.begin(), Y.begin() + n);
196
for (int i = 0; i < n; i++) {
204
bool StackTransform::remove_negative() {
206
while (s < n && A[s].first < d) {
211
for (int i = 0; i < n; i++) {
218
int StackTransform::try_load(int &i, int offs) const {
219
return i < n ? A[i++].first + offs : inf_x;
222
bool StackTransform::try_store(int x, int y) {
223
if (x == y || x < d) {
226
if (n == max_n || x != (short)x || y != (short)y) {
229
A[n].first = (short)x;
230
A[n++].second = (short)y;
235
bool StackTransform::compose(const StackTransform &a, const StackTransform &b, StackTransform &c) {
236
if (!a.is_valid() || !b.is_valid()) {
237
return c.invalidate();
241
c.dp = std::max(a.dp, b.dp + a.d);
245
int x1 = a.try_load(i);
246
int x2 = b.try_load(j, a.d);
249
int y = a.A[i - 1].second;
250
if (!c.try_store(x1, y)) {
254
} else if (x2 < inf_x) {
258
int y = b.A[j - 1].second;
259
if (!c.try_store(x2, a(y))) {
262
x2 = b.try_load(j, a.d);
270
bool StackTransform::apply(const StackTransform &other) {
272
if (!compose(*this, other, res)) {
279
bool StackTransform::preapply(const StackTransform &other) {
281
if (!compose(other, *this, res)) {
287
StackTransform StackTransform::operator*(const StackTransform &b) const & {
289
compose(*this, b, res);
294
StackTransform &StackTransform::operator*=(const StackTransform &other) {
296
(compose(*this, other, res) && assign(res)) || invalidate();
300
bool StackTransform::apply_xchg(int i, int j, bool relaxed) {
301
if (!is_valid() || i < 0 || j < 0) {
305
return relaxed || touch(i);
307
int u = touch_get(i), v = touch_get(j);
308
return set(i, v) && set(j, u);
311
bool StackTransform::apply_push(int i) {
312
if (!is_valid() || i < 0) {
315
int u = touch_get(i);
316
return shift(-1) && set(0, u);
319
bool StackTransform::apply_push_newconst() {
323
return shift(-1) && set(0, c_start - c++);
326
bool StackTransform::apply_pop(int i) {
327
if (!is_valid() || i < 0) {
331
return touch(0) && shift(1);
333
return set(i, get(0)) && shift(1);
337
bool StackTransform::apply_blkpop(int k) {
338
if (!is_valid() || k < 0) {
341
return !k || (touch(k - 1) && shift(k));
344
bool StackTransform::equal(const StackTransform &other, bool relaxed) const {
345
if (!is_valid() || !other.is_valid()) {
348
if (!(n == other.n && d == other.d)) {
351
for (int i = 0; i < n; i++) {
352
if (A[i] != other.A[i]) {
356
return relaxed || dp == other.dp;
359
StackTransform StackTransform::Xchg(int i, int j, bool relaxed) {
361
t.apply_xchg(i, j, relaxed);
365
StackTransform StackTransform::Push(int i) {
371
StackTransform StackTransform::Pop(int i) {
377
bool StackTransform::is_xchg(int i, int j) const {
381
return is_valid() && !d && n == 2 && i >= 0 && j >= 0 && get(i) == j && get(j) == i;
384
bool StackTransform::is_xchg(int *i, int *j) const {
385
if (!is_valid() || d || n > 2 || !dp) {
395
int a = A[0].first, b = A[1].first;
396
if (A[0].second != b || A[1].second != a) {
404
bool StackTransform::is_xchg_xchg(int i, int j, int k, int l) const {
405
if (is_valid() && !d && n <= 4 && (i | j | k | l) >= 0) {
407
return t.apply_xchg(i, j) && t.apply_xchg(k, l) && t <= *this;
413
bool StackTransform::is_xchg_xchg(int *i, int *j, int *k, int *l) const {
414
if (!is_valid() || d || n > 4 || !dp || !is_permutation()) {
418
*i = *j = *k = *l = 0;
423
return is_xchg(i, j);
429
int s = (b == A[2].first ? 2 : 1);
431
if (b != A[s].first || c != A[3 - s].first || a != A[3 - s].second) {
438
return is_xchg_xchg(*i, *j, *k, *l);
445
for (int s = 1; s < 4; s++) {
446
if (A[s].first != *j) {
449
return get(*l) == *k && is_xchg_xchg(*i, *j, *k, *l);
455
bool StackTransform::is_push(int i) const {
456
return is_valid() && d == -1 && n == 1 && A[0].first == -1 && A[0].second == i;
459
bool StackTransform::is_push(int *i) const {
460
if (is_valid() && d == -1 && n == 1 && A[0].first == -1 && A[0].second >= 0) {
473
bool StackTransform::is_pop(int i) const {
474
if (!is_valid() || d != 1 || n > 1 || i < 0) {
480
return n == 1 && A[0].first == i && !A[0].second;
483
bool StackTransform::is_pop(int *i) const {
484
if (!is_valid() || d != 1 || n > 1) {
491
if (n == 1 && !A[0].second) {
499
bool StackTransform::is_pop_pop(int i, int j) const {
500
if (is_valid() && d == 2 && n <= 2 && i >= 0 && j >= 0) {
502
return t.apply_pop(i) && t.apply_pop(j) && t <= *this;
508
bool StackTransform::is_pop_pop(int *i, int *j) const {
509
if (!is_valid() || d != 2 || n > 2) {
515
*i = A[0].first - A[0].second;
516
*j = A[1].first - A[1].second;
517
if (A[0].second > A[1].second) {
520
} else if (!A[0].second) {
527
return is_pop_pop(*i, *j);
530
const StackTransform StackTransform::rot{2, 0, 1, 3};
531
const StackTransform StackTransform::rot_rev{1, 2, 0, 3};
533
bool StackTransform::is_rot() const {
534
return equal(rot, true);
537
bool StackTransform::is_rotrev() const {
538
return equal(rot_rev, true);
542
bool StackTransform::is_push_rot(int i) const {
543
return is_valid() && d == -1 && i >= 0 && is_trivial_after(3) && get(0) == 1 && get(1) == i && get(2) == 0;
546
bool StackTransform::is_push_rot(int *i) const {
547
return is_valid() && (*i = get(1)) >= 0 && is_push_rot(*i);
551
bool StackTransform::is_push_rotrev(int i) const {
552
return is_valid() && d == -1 && i >= 0 && is_trivial_after(3) && get(0) == 0 && get(1) == 1 && get(2) == i;
555
bool StackTransform::is_push_rotrev(int *i) const {
556
return is_valid() && (*i = get(2)) >= 0 && is_push_rotrev(*i);
561
bool StackTransform::is_push_xchg(int i, int j, int k) const {
563
return is_valid() && d == -1 && n <= 3 && t.apply_push(i) && t.apply_xchg(j, k) && t <= *this;
566
bool StackTransform::is_push_xchg(int *i, int *j, int *k) const {
567
if (!(is_valid() && d == -1 && n <= 3 && n > 0)) {
585
return is_push_xchg(*i, *j, *k);
589
bool StackTransform::is_xchg2(int i, int j) const {
591
return is_valid() && !d && t.apply_xchg(1, i) && t.apply_xchg(0, j) && t <= *this;
594
bool StackTransform::is_xchg2(int *i, int *j) const {
595
if (!is_valid() || d || n > 4 || n == 1 || dp < 2) {
603
if (*i < 0 || *j < 0) {
608
} else if (n == 3 && *i) {
612
return is_xchg2(*i, *j);
619
bool StackTransform::is_xcpu(int i, int j) const {
621
return is_valid() && d == -1 && t.apply_xchg(0, i) && t.apply_push(j) && t <= *this;
624
bool StackTransform::is_xcpu(int *i, int *j) const {
625
if (!is_valid() || d != -1 || n > 3 || dp < 1) {
632
} else if (*j == *i) {
635
return is_xcpu(*i, *j);
639
bool StackTransform::is_puxc(int i, int j) const {
641
return is_valid() && d == -1 && t.apply_push(i) && t.apply_xchg(0, 1) && t.apply_xchg(0, j + 1) && t <= *this;
647
bool StackTransform::is_puxc(int *i, int *j) const {
648
if (!is_valid() || d != -1 || n > 3) {
653
if (!*i && is_push(*j)) {
655
return is_puxc(*i, *j);
660
return is_puxc(*i, *j);
664
bool StackTransform::is_push2(int i, int j) const {
666
return is_valid() && d == -2 && t.apply_push(i) && t.apply_push(j + 1) && t <= *this;
669
bool StackTransform::is_push2(int *i, int *j) const {
670
if (!is_valid() || d != -2 || n > 2) {
675
return is_push2(*i, *j);
679
bool StackTransform::is_xchg3(int *i, int *j, int *k) const {
680
if (!is_valid() || d || dp < 3 || !is_permutation()) {
683
for (int s = 2; s >= 0; s--) {
685
StackTransform t = Xchg(2, *i) * *this;
686
if (t.is_xchg2(j, k)) {
694
bool StackTransform::is_xc2pu(int *i, int *j, int *k) const {
695
if (!is_valid() || d != -1 || dp < 2) {
698
for (int s = 2; s >= 1; s--) {
700
StackTransform t = Xchg(1, *i) * *this;
701
if (t.is_xcpu(j, k)) {
709
bool StackTransform::is_xcpuxc(int *i, int *j, int *k) const {
710
if (!is_valid() || d != -1 || dp < 2) {
713
for (int s = 2; s >= 0; s--) {
715
StackTransform t = Xchg(1, *i) * *this;
716
if (t.is_puxc(j, k)) {
724
bool StackTransform::is_xcpu2(int *i, int *j, int *k) const {
725
if (!is_valid() || d != -2 || dp < 1) {
729
StackTransform t = Xchg(0, *i) * *this;
730
return t.is_push2(j, k);
740
bool StackTransform::is_puxc2(int *i, int *j, int *k) const {
741
if (!is_valid() || d != -1 || dp < 2) {
744
for (int s = 2; s >= 0; s--) {
746
if (preimage_count(*i) != 2) {
749
for (int u = -1; u <= 3; u++) {
750
*j = (u >= 2 ? get(u - 2) : u);
751
for (int v = -1; v <= 3; v++) {
752
*k = (v >= 2 ? get(v - 2) : v);
753
if (is_puxc2(*i, *j, *k)) {
763
bool StackTransform::is_puxc2(int i, int j, int k) const {
765
return is_valid() && d == -1 && dp >= 2
766
&& t.apply_push(i) && t.apply_xchg(0, 2)
767
&& t.apply_xchg(1, j + 1)
768
&& t.apply_xchg(0, k + 1) && t <= *this;
772
bool StackTransform::is_puxcpu(int *i, int *j, int *k) const {
773
if (!is_valid() || d != -2 || dp < 1) {
776
StackTransform t = *this;
777
if (t.apply_pop() && t.is_puxc(i, j)) {
779
auto v = t.preimage(y);
782
t.apply_push(*k + 1);
792
bool StackTransform::is_pu2xc(int *i, int *j, int *k) const {
793
if (!is_valid() || d != -2 || dp < 1) {
797
for (int v = -2; v <= 1; v++) {
798
*k = (v <= 0 ? v : get(0));
799
for (int u = -1; u <= 1; u++) {
800
*j = (u <= 0 ? u : get(v != -1));
801
if (is_pu2xc(*i, *j, *k)) {
809
bool StackTransform::is_pu2xc(int i, int j, int k) const {
811
return is_valid() && d == -2 && dp >= 1
812
&& t.apply_push(i) && t.apply_xchg(0, 1)
813
&& t.apply_push(j + 1) && t.apply_xchg(0, 1)
814
&& t.apply_xchg(0, k + 2) && t <= *this;
818
bool StackTransform::is_push3(int i, int j, int k) const {
820
return is_valid() && d == -3 && t.apply_push(i) && t.apply_push(j + 1) && t.apply_push(k + 2) && t <= *this;
823
bool StackTransform::is_push3(int *i, int *j, int *k) const {
824
if (!is_valid() || d != -3 || n > 3) {
830
return is_push3(*i, *j, *k);
833
bool StackTransform::is_blkswap(int *i, int *j) const {
834
if (!is_valid() || d || !is_permutation()) {
841
auto v = preimage(0);
846
return *i > 0 && is_blkswap(*i, *j);
849
bool StackTransform::is_blkswap(int i, int j) const {
850
if (!is_valid() || d || i <= 0 || j <= 0 || dp < i + j || !is_trivial_after(i + j)) {
853
for (int s = 0; s < i; s++) {
854
if (get(s) != s + j) {
858
for (int s = 0; s < j; s++) {
859
if (get(s + i) != s) {
867
bool StackTransform::is_blkdrop(int *i) const {
868
if (is_valid() && d > 0 && !n) {
876
bool StackTransform::is_blkdrop2(int i, int j) const {
877
if (!is_valid() || d != i || i <= 0 || j < 0 || dp < i + j || n != j || !is_trivial_after(j)) {
880
for (int s = 0; s < j; s++) {
888
bool StackTransform::is_blkdrop2(int *i, int *j) const {
889
if (is_valid() && is_blkdrop2(d, n)) {
898
bool StackTransform::is_blkpush(int *i, int *j) const {
899
if (!is_valid() || d >= 0) {
904
return is_blkpush(*i, *j);
907
bool StackTransform::is_blkpush(int i, int j) const {
908
if (!is_valid() || d >= 0 || d != -i || j < 0 || dp < i + j || !is_trivial_after(i)) {
912
for (int s = 0; s < i; s++) {
913
if (!t.apply_push(j)) {
920
bool StackTransform::is_reverse(int *i, int *j) const {
921
if (!is_valid() || d || !is_permutation() || n < 2) {
925
*i = A[n - 1].first - A[0].first + 1;
926
return is_reverse(*i, *j);
929
bool StackTransform::is_reverse(int i, int j) const {
930
if (!is_valid() || d || !is_trivial_after(i + j) || n < 2 || A[0].first != j || A[n - 1].first != j + i - 1) {
933
for (int s = 0; s < i; s++) {
934
if (get(j + s) != j + i - 1 - s) {
943
bool StackTransform::is_nip_seq(int i, int j) const {
944
return is_valid() && d == i && i > j && j >= 0 && n == 1 && A[0].first == i && A[0].second == j;
947
bool StackTransform::is_nip_seq(int *i) const {
949
return is_nip_seq(*i);
952
bool StackTransform::is_nip_seq(int *i, int *j) const {
953
if (is_valid() && n > 0) {
956
return is_nip_seq(*i, *j);
963
bool StackTransform::is_pop_blkdrop(int i, int k) const {
965
return is_valid() && d == k + 1 && t.apply_pop(i) && t.apply_blkpop(k) && t <= *this;
970
bool StackTransform::is_pop_blkdrop(int *i, int *k) const {
971
if (is_valid() && n == 1 && d > 0 && !A[0].second) {
974
return is_pop_blkdrop(*i, *k);
981
bool StackTransform::is_2pop_blkdrop(int i, int j, int k) const {
983
return is_valid() && d == k + 2 && t.apply_pop(i) && t.apply_pop(j) && t.apply_blkpop(k) && t <= *this;
988
bool StackTransform::is_2pop_blkdrop(int *i, int *j, int *k) const {
989
if (is_valid() && n == 2 && d >= 2 && A[0].second + A[1].second == 1) {
991
int t = (A[0].second > 0);
993
*j = A[1 - t].first - 1;
994
return is_2pop_blkdrop(*i, *j, *k);
1001
bool StackTransform::is_const_rot(int c) const {
1002
return is_valid() && d == -1 && is_trivial_after(3) && get(0) == 1 && c <= c_start && get(1) == c && get(2) == 0;
1005
bool StackTransform::is_const_rot(int *c) const {
1006
return is_valid() && (*c = get(1)) <= c_start && is_const_rot(*c);
1010
bool StackTransform::is_const_pop(int c, int i) const {
1011
return is_valid() && !d && n == 1 && i > 0 && c <= c_start && get(i - 1) == c;
1014
bool StackTransform::is_const_pop(int *c, int *i) const {
1015
if (is_valid() && !d && n == 1 && A[0].second <= c_start) {
1016
*i = A[0].first + 1;
1018
return is_const_pop(*c, *i);
1025
bool StackTransform::is_push_const(int i, int c) const {
1026
return is_valid() && d == -2 && c <= c_start && i >= 0 && is_trivial_after(2) && get(0) == c && get(1) == i;
1029
bool StackTransform::is_push_const(int *i, int *c) const {
1030
return is_valid() && d == -2 && n == 2 && is_push_const(*i = get(1), *c = get(0));
1033
void StackTransform::show(std::ostream &os, int mode) const {
1039
if (n > 0 && A[0].first < d) {
1040
mi = A[0].first - d;
1043
ma = std::max(ma, A[n - 1].first - d + 1);
1045
ma = std::max(ma + 1, dp - d);
1050
for (int i = mi; i < ma; i++) {
1051
os << get(i) << (i == -1 ? '?' : (i == dp - d - 1 ? '|' : ' '));
1053
os << get(ma) << "..}";