From 16e942ff9f86c719c2f863a8d952e886186306fd Mon Sep 17 00:00:00 2001 From: kzrnm Date: Sat, 28 Dec 2024 04:30:38 +0900 Subject: [PATCH] AtCoder Library Practice Contest --- .../A - Disjoint Set Union.cs | 39 ++++++++++ .../B - Fenwick Tree.cs | 42 +++++++++++ .../C - Floor Sum.cs | 24 +++++++ .../D - Maxflow.cs | 71 +++++++++++++++++++ .../E - MinCostFlow.cs | 55 ++++++++++++++ .../F - Convolution.cs | 7 ++ .../G - SCC.cs | 29 ++++++++ .../H - Two SAT.cs | 41 +++++++++++ .../I - Number of Substrings.cs | 6 ++ .../J - Segment Tree.cs | 31 ++++++++ .../K - Range Affine Range Sum.cs | 49 +++++++++++++ .../L - Lazy Segment Tree.cs | 53 ++++++++++++++ .../README.md | 3 + 13 files changed, 450 insertions(+) create mode 100644 Sample/AtCoder Library Practice Contest/A - Disjoint Set Union.cs create mode 100644 Sample/AtCoder Library Practice Contest/B - Fenwick Tree.cs create mode 100644 Sample/AtCoder Library Practice Contest/C - Floor Sum.cs create mode 100644 Sample/AtCoder Library Practice Contest/D - Maxflow.cs create mode 100644 Sample/AtCoder Library Practice Contest/E - MinCostFlow.cs create mode 100644 Sample/AtCoder Library Practice Contest/F - Convolution.cs create mode 100644 Sample/AtCoder Library Practice Contest/G - SCC.cs create mode 100644 Sample/AtCoder Library Practice Contest/H - Two SAT.cs create mode 100644 Sample/AtCoder Library Practice Contest/I - Number of Substrings.cs create mode 100644 Sample/AtCoder Library Practice Contest/J - Segment Tree.cs create mode 100644 Sample/AtCoder Library Practice Contest/K - Range Affine Range Sum.cs create mode 100644 Sample/AtCoder Library Practice Contest/L - Lazy Segment Tree.cs create mode 100644 Sample/AtCoder Library Practice Contest/README.md diff --git a/Sample/AtCoder Library Practice Contest/A - Disjoint Set Union.cs b/Sample/AtCoder Library Practice Contest/A - Disjoint Set Union.cs new file mode 100644 index 0000000..7cc788f --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/A - Disjoint Set Union.cs @@ -0,0 +1,39 @@ +using AtCoder; + +var (n, q) = Console.ReadLine().Split().Select(int.Parse).ToTuple2(); +var dsu = new Dsu(n); + +while (--q >= 0) +{ + var (t, u, v) = Console.ReadLine().Split().Select(int.Parse).ToTuple3(); + if (t == 0) + { + dsu.Merge(u, v); + } + else + { + Console.WriteLine(dsu.Same(u, v) ? 1 : 0); + } +} + + +static class Extension +{ + public static (T, T) ToTuple2(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.Dispose(); + return (v0, v1); + } + public static (T, T, T) ToTuple3(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.MoveNext(); var v2 = e.Current; + e.Dispose(); + return (v0, v1, v2); + } +} \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/B - Fenwick Tree.cs b/Sample/AtCoder Library Practice Contest/B - Fenwick Tree.cs new file mode 100644 index 0000000..3c2571a --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/B - Fenwick Tree.cs @@ -0,0 +1,42 @@ +using AtCoder; + +var (n, q) = Console.ReadLine().Split().Select(int.Parse).ToTuple2(); +var fw = new FenwickTree(n); +var line = Console.ReadLine().Split().Select(int.Parse).ToArray(); +for (var i = 0; i < n; i++) + fw.Add(i, line[i]); + +while (--q >= 0) +{ + var (t, l, r) = Console.ReadLine().Split().Select(int.Parse).ToTuple3(); + if (t == 0) + { + fw.Add(l, r); + } + else + { + Console.WriteLine(fw[l..r]); + } +} + + +static class Extension +{ + public static (T, T) ToTuple2(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.Dispose(); + return (v0, v1); + } + public static (T, T, T) ToTuple3(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.MoveNext(); var v2 = e.Current; + e.Dispose(); + return (v0, v1, v2); + } +} \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/C - Floor Sum.cs b/Sample/AtCoder Library Practice Contest/C - Floor Sum.cs new file mode 100644 index 0000000..34b5dcc --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/C - Floor Sum.cs @@ -0,0 +1,24 @@ +using AtCoder; + +int t = int.Parse(Console.ReadLine()); + +while (--t >= 0) +{ + var (n, m, a, b) = Console.ReadLine().Split().Select(int.Parse).ToTuple4(); + + Console.WriteLine(MathLib.FloorSum(n, m, a, b)); +} + +static class Extension +{ + public static (T, T, T, T) ToTuple4(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.MoveNext(); var v2 = e.Current; + e.MoveNext(); var v3 = e.Current; + e.Dispose(); + return (v0, v1, v2, v3); + } +} \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/D - Maxflow.cs b/Sample/AtCoder Library Practice Contest/D - Maxflow.cs new file mode 100644 index 0000000..0a9db5a --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/D - Maxflow.cs @@ -0,0 +1,71 @@ +using AtCoder; + +var (n, m) = Console.ReadLine().Split().Select(int.Parse).ToTuple2(); +var S = Enumerable.Range(0, n).Select(_ => Console.ReadLine().ToCharArray()).ToArray(); +ReadOnlySpan<(int, int)> moves = [ + (0, -1), + (0, +1), + (-1, 0), + (+1, 0), +]; + +var mf = new MfGraph(n * m + 2); + +var start = n * m; +var goal = start + 1; +for (int h = 0; h < n; h++) + for (int w = 0; w < m; w++) + { + var ix = h * m + w; + if (S[h][w] != '.') continue; + if ((h ^ w) % 2 != 0) + { + foreach (var (mh, mw) in moves) + { + var dh = h + mh; + var dw = w + mw; + + if ((uint)dh < n && (uint)dw < m && S[dh][dw] == '.') + { + var dx = dh * m + dw; + mf.AddEdge(ix, dx, 1); + } + } + mf.AddEdge(start, ix, 1); + } + else + mf.AddEdge(ix, goal, 1); + } +Console.WriteLine(mf.Flow(start, goal)); +foreach (var e in mf.Edges()) +{ + if (e.From >= start || e.To >= start || e.Flow == 0) continue; + var ix1 = e.From; + var ix2 = e.To; + if (ix1 > ix2) (ix1, ix2) = (ix2, ix1); + if (ix1 + m != ix2) + { + S[ix1 / m][ix1 % m] = '>'; + S[ix2 / m][ix2 % m] = '<'; + } + else + { + S[ix1 / m][ix1 % m] = 'v'; + S[ix2 / m][ix2 % m] = '^'; + } +} +foreach (var line in S) +{ + Console.WriteLine(line); +} +static class Extension +{ + public static (T, T) ToTuple2(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.Dispose(); + return (v0, v1); + } +} \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/E - MinCostFlow.cs b/Sample/AtCoder Library Practice Contest/E - MinCostFlow.cs new file mode 100644 index 0000000..cefa410 --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/E - MinCostFlow.cs @@ -0,0 +1,55 @@ +using AtCoder; + +var (n, K) = Console.ReadLine().Split().Select(int.Parse).ToTuple2(); + +var g = new McfGraph(2 * n + 2); +int s = 2 * n, t = 2 * n + 1; + +// we can "waste" the flow +g.AddEdge(s, t, n * K, int.MaxValue); + +for (int i = 0; i < n; i++) +{ + g.AddEdge(s, i, K, 0); + g.AddEdge(n + i, t, K, 0); +} + +for (int i = 0; i < n; i++) +{ + var line = Console.ReadLine().Split().Select(int.Parse).ToArray(); + for (int j = 0; j < line.Length; j++) + { + long a = line[j]; + g.AddEdge(i, n + j, 1, int.MaxValue - a); + } +} +var result = g.Flow(s, t, n * K); +Console.WriteLine((long)n * K * int.MaxValue - result.cost); + +var grid = Enumerable.Range(0, n).Select(MakeLine).ToArray(); +foreach (var e in g.Edges()) +{ + if (e.From == s || e.To == t || e.Flow == 0) continue; + grid[e.From][e.To - n] = 'X'; +} +foreach (var line in grid) +{ + Console.WriteLine(line); +} +char[] MakeLine(int _) +{ + var rt = new char[n]; + rt.AsSpan().Fill('.'); + return rt; +} +static class Extension +{ + public static (T, T) ToTuple2(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.Dispose(); + return (v0, v1); + } +} \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/F - Convolution.cs b/Sample/AtCoder Library Practice Contest/F - Convolution.cs new file mode 100644 index 0000000..211ab46 --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/F - Convolution.cs @@ -0,0 +1,7 @@ +using AtCoder; + +Console.ReadLine(); +var a = Console.ReadLine().Split().Select(int.Parse).ToArray(); +var b = Console.ReadLine().Split().Select(int.Parse).ToArray(); + +Console.WriteLine(string.Join(' ', MathLib.Convolution(a, b))); \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/G - SCC.cs b/Sample/AtCoder Library Practice Contest/G - SCC.cs new file mode 100644 index 0000000..5719103 --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/G - SCC.cs @@ -0,0 +1,29 @@ +using AtCoder; + +var (n, m) = Console.ReadLine().Split().Select(int.Parse).ToTuple2(); +var scc = new SccGraph(n); + +while (--m >= 0) +{ + var (a, b) = Console.ReadLine().Split().Select(int.Parse).ToTuple2(); + scc.AddEdge(a, b); +} + +var groups = scc.Scc(); +Console.WriteLine(groups.Length); +foreach (var g in groups) +{ + Console.WriteLine(string.Join(' ', g.Prepend(g.Length))); +} + +static class Extension +{ + public static (T, T) ToTuple2(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.Dispose(); + return (v0, v1); + } +} \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/H - Two SAT.cs b/Sample/AtCoder Library Practice Contest/H - Two SAT.cs new file mode 100644 index 0000000..759f0d9 --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/H - Two SAT.cs @@ -0,0 +1,41 @@ +using AtCoder; +using static System.Math; + +var (n, D) = Console.ReadLine().Split().Select(int.Parse).ToTuple2(); +(int X, int Y)[] XY = Enumerable.Range(0, n).Select(_ => Console.ReadLine().Split().Select(int.Parse).ToTuple2()).ToArray(); +var ts = new TwoSat(n); +for (int i = 0; i < XY.Length; i++) +{ + var (x1, y1) = XY[i]; + for (int j = i + 1; j < XY.Length; j++) + { + var (x2, y2) = XY[j]; + if (Abs(x1 - x2) < D) ts.AddClause(i, true, j, true); + if (Abs(x1 - y2) < D) ts.AddClause(i, true, j, false); + if (Abs(y1 - x2) < D) ts.AddClause(i, false, j, true); + if (Abs(y1 - y2) < D) ts.AddClause(i, false, j, false); + } +} +if (ts.Satisfiable()) +{ + Console.WriteLine("Yes"); + var rt = ts.Answer(); + foreach (var v in rt.Zip(XY, (b, t) => b ? t.Y : t.X)) + Console.WriteLine(v); +} +else +{ + Console.WriteLine("No"); +} + +static class Extension +{ + public static (T, T) ToTuple2(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.Dispose(); + return (v0, v1); + } +} \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/I - Number of Substrings.cs b/Sample/AtCoder Library Practice Contest/I - Number of Substrings.cs new file mode 100644 index 0000000..d6d4c67 --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/I - Number of Substrings.cs @@ -0,0 +1,6 @@ +using AtCoder; + +var s = Console.ReadLine(); +var sa = StringLib.SuffixArray(s); + +Console.WriteLine((long)(s.Length + 1) * s.Length / 2 - StringLib.LcpArray(s, sa).Select(i => (long)i).Sum()); \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/J - Segment Tree.cs b/Sample/AtCoder Library Practice Contest/J - Segment Tree.cs new file mode 100644 index 0000000..95b6020 --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/J - Segment Tree.cs @@ -0,0 +1,31 @@ +using AtCoder; + +var line = Console.ReadLine().Split(' '); +var N = int.Parse(line[0]); +var Q = int.Parse(line[1]); +var seg = new Segtree(Console.ReadLine().Split(' ').Select(long.Parse).ToArray()); + +for (int q = 0; q < Q; q++) +{ + line = Console.ReadLine().Split(' '); + int t = int.Parse(line[0]); + int l = int.Parse(line[1]) - 1; + int r = int.Parse(line[2]); + switch (t) + { + case 1: + seg[l] = r; + break; + case 2: + Console.WriteLine(seg.Prod(l, r)); + break; + case 3: + Console.WriteLine(1 + seg.MaxRight(l, num => num < r)); + break; + } +} +struct Op : ISegtreeOperator +{ + public long Identity => long.MinValue; + public long Operate(long x, long y) => Math.Max(x, y); +} diff --git a/Sample/AtCoder Library Practice Contest/K - Range Affine Range Sum.cs b/Sample/AtCoder Library Practice Contest/K - Range Affine Range Sum.cs new file mode 100644 index 0000000..c57c885 --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/K - Range Affine Range Sum.cs @@ -0,0 +1,49 @@ +using AtCoder; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +DynamicModInt.Mod = 998244353; + +var (n, Q) = Console.ReadLine().Split().Select(int.Parse).ToTuple2(); +var seg = new LazySegtree(Console.ReadLine().Split().Select(v => new S(int.Parse(v))).ToArray()); +for (int q = 0; q < Q; q++) +{ + var line = Console.ReadLine().Split().Select(int.Parse).ToArray(); + int t = line[0]; + int l = line[1]; + int r = line[2]; + if (t == 0) + { + var b = line[3]; + var c = line[4]; + seg.Apply(l, r, new(b, c)); + } + else + Console.WriteLine(seg[l..r].Value); +} + +readonly record struct Affine(DynamicModInt b, DynamicModInt c); +readonly record struct S(DynamicModInt Value, uint Length = 1); + +readonly struct Op : ILazySegtreeOperator +{ + [MethodImpl(256)] + public S Operate(S x, S y) => new(x.Value + y.Value, x.Length + y.Length); + [MethodImpl(256)] + public S Mapping(Affine f, S x) => new(f.b * x.Value + f.c * x.Length, x.Length); + [MethodImpl(256)] + public Affine Composition(Affine f, Affine g) => new(f.b * g.b, f.b * g.c + f.c); + public S Identity => new(0, 0); + public Affine FIdentity => new(1, 0); +} +static class Extension +{ + public static (T, T) ToTuple2(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.Dispose(); + return (v0, v1); + } +} \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/L - Lazy Segment Tree.cs b/Sample/AtCoder Library Practice Contest/L - Lazy Segment Tree.cs new file mode 100644 index 0000000..6463a2c --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/L - Lazy Segment Tree.cs @@ -0,0 +1,53 @@ +using AtCoder; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +var (n, Q) = Console.ReadLine().Split().Select(int.Parse).ToTuple2(); +var A = Console.ReadLine().Split().Select(c => c == "1" ? new P(0, 1) : new P(1, 0)).ToArray(); +var seg = new LazySegtree(A); + +while (--Q >= 0) +{ + var (t, l, r) = Console.ReadLine().Split().Select(int.Parse).ToTuple3(); + --l; + + if (t == 1) + seg.Apply(l, r, true); + else + Console.WriteLine(seg[l..r].Sum); +} + +readonly record struct P(int Zero, int One, long Sum = 0, long Inv = 0); + +readonly record struct Op : ILazySegtreeOperator +{ + [MethodImpl(256)] + public P Operate(P x, P y) => new(x.Zero + y.Zero, x.One + y.One, x.Sum + y.Sum + (long)x.One * y.Zero, x.Inv + y.Inv + (long)y.One * x.Zero); + [MethodImpl(256)] + public P Mapping(bool f, P x) => f ? new(x.One, x.Zero, x.Inv, x.Sum) : x; + [MethodImpl(256)] + public bool Composition(bool nf, bool cf) => nf != cf; + + public P Identity => default; + public bool FIdentity => default; +} +static class Extension +{ + public static (T, T) ToTuple2(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.Dispose(); + return (v0, v1); + } + public static (T, T, T) ToTuple3(this IEnumerable t) + { + var e = t.GetEnumerator(); + e.MoveNext(); var v0 = e.Current; + e.MoveNext(); var v1 = e.Current; + e.MoveNext(); var v2 = e.Current; + e.Dispose(); + return (v0, v1, v2); + } +} \ No newline at end of file diff --git a/Sample/AtCoder Library Practice Contest/README.md b/Sample/AtCoder Library Practice Contest/README.md new file mode 100644 index 0000000..6083b9f --- /dev/null +++ b/Sample/AtCoder Library Practice Contest/README.md @@ -0,0 +1,3 @@ +# AtCoder Library Practice Contest + +Samples for [AtCoder Library Practice Contest](https://atcoder.jp/contests/practice2) \ No newline at end of file