-
Notifications
You must be signed in to change notification settings - Fork 0
/
20b.cs
134 lines (119 loc) · 4.38 KB
/
20b.cs
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
129
130
131
132
133
134
// d=$(mktemp -d) && pushd $d >/dev/null && dotnet new console >/dev/null && popd >/dev/null && cp 20b.cs $d/Program.cs && dotnet run --project $d
class Program {
enum Kind {
BEGIN, FLIP, CONJ, OTHER,
}
static long Solve(int[][] g, int[][] gt, Kind[] kind, int end) {
var n = g.Length;
var mem = new bool[n][];
for (var i = 0; i < n; i++) {
var len = kind[i] == Kind.BEGIN || kind[i] == Kind.OTHER ? 0 : kind[i] == Kind.FLIP ? 1 : gt[i].Length;
mem[i] = new bool[len];
}
var index = new int[n, n];
for (var i = 0; i < n; i++) {
for (var j = 0; j < n; j++) if (kind[j] == Kind.CONJ) {
index[i, j] = -1;
for (var k = 0; k < gt[j].Length; k++) {
if (gt[j][k] == i) {
index[i, j] = k;
}
}
}
}
var begin = 0;
while (kind[begin] != Kind.BEGIN) begin++;
var queue = new Queue<int>();
for (var it = 1L;; it++) {
var lows = 0;
queue.Clear();
queue.Enqueue(begin * 2);
while (queue.Count > 0) {
var value = queue.Dequeue();
var v = value / 2;
var high = (value & 1) == 1;
if (v == end) {
if (!high) lows++;
continue;
}
var k = kind[v];
var sendHigh = false;
if (k == Kind.FLIP) {
if (high) continue;
mem[v][0] = !mem[v][0];
sendHigh = mem[v][0];
} else if (k == Kind.CONJ) {
sendHigh = mem[v].Any(x => !x);
}
foreach (var target in g[v]) {
if (kind[target] == Kind.CONJ) {
mem[target][index[v, target]] = sendHigh;
}
queue.Enqueue(target * 2 + (sendHigh ? 1 : 0));
}
}
if (lows == 1) return it;
}
}
static void Main() {
var v2i = new Dictionary<string, int>();
var i2v = new Dictionary<int, string>();
var g = new Dictionary<int, List<int>>();
var gt = new Dictionary<int, List<int>>();
var kind = new Dictionary<int, Kind>();
int vertex(string name) {
if (!v2i.ContainsKey(name)) {
var v = v2i.Count;
v2i[name] = v;
i2v[v] = name;
g[v] = new List<int>();
gt[v] = new List<int>();
kind[v] = Kind.OTHER;
}
return v2i[name];
}
void addEdge(int x, int y) {
g[x].Add(y);
gt[y].Add(x);
}
while (true) {
var line = Console.In.ReadLine();
if (line == null) break;
var str = line.Split(" -> ");
var nk = str[0];
var (name, k) =
nk[0] == '%' ? (nk.Substring(1), Kind.FLIP) :
nk[0] == '&' ? (nk.Substring(1), Kind.CONJ) :
(nk, Kind.BEGIN);
var v = vertex(name);
kind[v] = k;
foreach (var u in str[1].Split(", ")) {
addEdge(v, vertex(u));
}
}
var end = v2i["rx"];
var gl = new int[g.Count][];
var gtl = new int[gt.Count][];
var kl = new Kind[kind.Count];
for (var i = 0; i < g.Count; i++) gl[i] = g[i].ToArray();
for (var i = 0; i < gt.Count; i++) gtl[i] = gt[i].ToArray();
for (var i = 0; i < kind.Count; i++) kl[i] = kind[i];
/*
for (var i = 0; i < g.Count; i++) {
var it = i == end ? "" : kind[i] == Kind.FLIP ? "%" : kind[i] == Kind.CONJ ? "&" : "";
foreach (var j in g[i]) {
var jt = j == end ? "" : kind[j] == Kind.FLIP ? "%" : kind[j] == Kind.CONJ ? "&" : "";
Console.WriteLine(it + i2v[i] + " " + jt + i2v[j]);
}
}
// See 20b.png. (Drawn with https://csacademy.com/app/graph_editor/)
*/
var result = 1L;
for (var i = 0; i < g.Count; i++) {
if (kind[i] == Kind.CONJ && g[i].Count == 1 && gt[i].Count == 1) {
result *= Solve(gl, gtl, kl, i);
}
}
Console.WriteLine(result);
}
}