#include <iostream>
#include <vector>
using namespace std;
struct ZB1 {
struct Zbior {
int const j;
Zbior *neg;
Zbior(int j = 0) : j(j), neg(0) {
}
virtual ~Zbior() {
}
virtual bool check(int value) const {
return !(value % j);
}
};
struct ZbiorSuma : Zbior {
Zbior const &a, &b;
ZbiorSuma(Zbior const &a, Zbior const &b) : a(a), b(b) {
}
virtual bool check(int v) const {
return a.check(v) || b.check(v);
}
};
struct ZbiorIloczyn : Zbior {
Zbior const &a, &b;
ZbiorIloczyn(Zbior const &a, Zbior const &b) : a(a), b(b) {
}
virtual bool check(int v) const {
return a.check(v) && b.check(v);
}
};
struct ZbiorNegacja : Zbior {
Zbior const &a;
ZbiorNegacja(Zbior const &a) : a(a) {
}
virtual bool check(int v) const {
return !a.check(v);
}
};
int count, m;
vector< Zbior * > v, tofree;
ZB1(int n, int m) : count(1 + n), m(m), v(1 + count + m) {
int i = 0;
while (++i <= n)
tofree.push_back(v[i] = new Zbior(i));
}
~ZB1() {
int i = tofree.size();
while (i--)
delete tofree[i];
}
void suma(int x, int y) {
tofree.push_back(v[count++] = new ZbiorSuma(*v[x], *v[y]));
}
void iloczyn(int x, int y) {
tofree.push_back(v[count++] = new ZbiorIloczyn(*v[x], *v[y]));
}
void negacja(int x) {
Zbior *z = v[x];
if (!z->neg) {
(z->neg = new ZbiorNegacja(*z))->neg = z;
tofree.push_back(z->neg);
}
v[count++] = z->neg;
}
bool check(int value) const {
return v[count - 1]->check(value);
}
};
struct ZB2 : ZB1 {
vector< int > vc, vx, vy;
ZB2(int n, int m) : ZB1(n, m) {
}
void add(int c, int x, int y = 0) {
vc.push_back(c);
vx.push_back(x);
vy.push_back(y);
}
void suma(int x, int y) {
add(1, x, y);
ZB1::suma(x, y);
}
void iloczyn(int x, int y) {
add(2, x, y);
ZB1::iloczyn(x, y);
}
void negacja(int x) {
add(3, x);
ZB1::negacja(x);
}
friend ostream &operator<<(ostream &os, const ZB2 &zb2) {
int i = 0;
os << zb2.vc.size() << '\n';
while (i < (int)zb2.vc.size()) {
os << zb2.vc[i] << ' ' << zb2.vx[i];
if (zb2.vy[i])
os << ' ' << zb2.vy[i];
os << '\n';
++i;
}
return os;
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, s, i, b = 0;
cin >> n >> s;
ZB2 zb2(n, n * 2);
for (i = 1; i <= n; ++i)
zb2.negacja(i);
for (i = 1; i <= n; ++i) {
if (i > b) {
if (s) {
--s;
cin >> b;
} else
b = n + 1;
}
if (zb2.check(i) != (i == b)) {
if (i == b)
zb2.suma(zb2.count - 1, i);
else
zb2.iloczyn(zb2.count - 1, n + i);
}
}
cout << zb2;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #include <iostream> #include <vector> using namespace std; struct ZB1 { struct Zbior { int const j; Zbior *neg; Zbior(int j = 0) : j(j), neg(0) { } virtual ~Zbior() { } virtual bool check(int value) const { return !(value % j); } }; struct ZbiorSuma : Zbior { Zbior const &a, &b; ZbiorSuma(Zbior const &a, Zbior const &b) : a(a), b(b) { } virtual bool check(int v) const { return a.check(v) || b.check(v); } }; struct ZbiorIloczyn : Zbior { Zbior const &a, &b; ZbiorIloczyn(Zbior const &a, Zbior const &b) : a(a), b(b) { } virtual bool check(int v) const { return a.check(v) && b.check(v); } }; struct ZbiorNegacja : Zbior { Zbior const &a; ZbiorNegacja(Zbior const &a) : a(a) { } virtual bool check(int v) const { return !a.check(v); } }; int count, m; vector< Zbior * > v, tofree; ZB1(int n, int m) : count(1 + n), m(m), v(1 + count + m) { int i = 0; while (++i <= n) tofree.push_back(v[i] = new Zbior(i)); } ~ZB1() { int i = tofree.size(); while (i--) delete tofree[i]; } void suma(int x, int y) { tofree.push_back(v[count++] = new ZbiorSuma(*v[x], *v[y])); } void iloczyn(int x, int y) { tofree.push_back(v[count++] = new ZbiorIloczyn(*v[x], *v[y])); } void negacja(int x) { Zbior *z = v[x]; if (!z->neg) { (z->neg = new ZbiorNegacja(*z))->neg = z; tofree.push_back(z->neg); } v[count++] = z->neg; } bool check(int value) const { return v[count - 1]->check(value); } }; struct ZB2 : ZB1 { vector< int > vc, vx, vy; ZB2(int n, int m) : ZB1(n, m) { } void add(int c, int x, int y = 0) { vc.push_back(c); vx.push_back(x); vy.push_back(y); } void suma(int x, int y) { add(1, x, y); ZB1::suma(x, y); } void iloczyn(int x, int y) { add(2, x, y); ZB1::iloczyn(x, y); } void negacja(int x) { add(3, x); ZB1::negacja(x); } friend ostream &operator<<(ostream &os, const ZB2 &zb2) { int i = 0; os << zb2.vc.size() << '\n'; while (i < (int)zb2.vc.size()) { os << zb2.vc[i] << ' ' << zb2.vx[i]; if (zb2.vy[i]) os << ' ' << zb2.vy[i]; os << '\n'; ++i; } return os; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, s, i, b = 0; cin >> n >> s; ZB2 zb2(n, n * 2); for (i = 1; i <= n; ++i) zb2.negacja(i); for (i = 1; i <= n; ++i) { if (i > b) { if (s) { --s; cin >> b; } else b = n + 1; } if (zb2.check(i) != (i == b)) { if (i == b) zb2.suma(zb2.count - 1, i); else zb2.iloczyn(zb2.count - 1, n + i); } } cout << zb2; } |
English