結果
| 問題 |
No.3345 Reducible Sequence
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-11-13 21:57:08 |
| 言語 | C# (.NET 8.0.404) |
| 結果 |
AC
|
| 実行時間 | 501 ms / 2,000 ms |
| コード長 | 4,546 bytes |
| コンパイル時間 | 11,196 ms |
| コンパイル使用メモリ | 171,308 KB |
| 実行使用メモリ | 197,768 KB |
| 最終ジャッジ日時 | 2025-11-13 21:57:43 |
| 合計ジャッジ時間 | 17,241 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 26 |
コンパイルメッセージ
復元対象のプロジェクトを決定しています... /home/judge/data/code/main.csproj を復元しました (145 ミリ秒)。 main -> /home/judge/data/code/bin/Release/net8.0/main.dll main -> /home/judge/data/code/bin/Release/net8.0/publish/
ソースコード
#nullable enable
#region
var (_input, _iter) = (Array.Empty<string>(), 0);
T I<T>() where T : IParsable<T>
{
while (_iter >= _input.Length) (_input, _iter) = (Console.ReadLine()!.Split(' '), 0);
return T.Parse(_input[_iter++], null);
}
#endregion
static T[] Range<T>(int n, Func<T> F) => Enumerable.Range(0, n).Select(_ => F()).ToArray();
var n = I<int>();
var az = Range(n, I<int>);
var divz = new List<int>[n];
for (var i = 0; i < n; i++)
{
var a = az[i];
var al = new List<int>();
for (var j = 1; j <= 80; j++)
{
if (a % j == 0)
{
var k = a / j;
al.Add(j);
if (k > j) al.Add(k);
}
}
al.Sort();
divz[i] = al;
}
bool Solve(int x)
{
var g = new MaximumFlow(n + x + 2);
var s = 0;
var t = n + x + 1;
for (var i = 1; i <= n; i++) g.AddEdge(s, i, 1);
for (var i = 1; i <= x; i++) g.AddEdge(i + n, t, 1);
for (var i = 1; i <= n; i++)
{
var al = divz[i - 1];
foreach (var div in al)
{
if (div > x) break;
g.AddEdge(i, div + n, 1);
}
}
var f = g.Flow(s, t);
return f >= x;
}
var pass = 1;
var fail = n + 1;
while (Math.Abs(pass - fail) > 1)
{
var mid = (pass + fail) >> 1;
if (Solve(mid)) pass = mid;
else fail = mid;
}
Console.WriteLine(pass);
class MaximumFlow
{
int N { get; init; }
List<(int next, long capacity, int reverse)> Edges { get; init; }
List<int>[] G { get; init; }
int[] Depths { get; set; } = Array.Empty<int>();
int[] Iter { get; set; } = Array.Empty<int>();
public MaximumFlow(int n)
{
N = n;
Edges = new List<(int, long, int)>();
G = new List<int>[n];
for (var i = 0; i < n; i++) G[i] = new List<int>();
}
public void AddEdge(int ab, int ad, long capacity)
{
G[ab].Add(Edges.Count);
Edges.Add((ad, capacity, Edges.Count + 1));
G[ad].Add(Edges.Count);
Edges.Add((ab, 0, Edges.Count - 1));
}
public long Flow(int s, int t) // s must not be equal to t
{
var res = 0L;
SetDepths(s);
while (Depths[t] >= 0)
{
Iter = new int[N];
long f;
while ((f = Flow(s, t, long.MaxValue)) > 0) res += f;
SetDepths(s);
}
return res;
}
void SetDepths(int s)
{
var (n, depths, g, edges) = (N, new int[N], G, Edges);
for (var i = 0; i < n; i++) depths[i] = -1;
depths[s] = 0;
var q = new Queue<int>();
q.Enqueue(s);
while (q.Count > 0)
{
var v = q.Dequeue();
var w = depths[v] + 1;
foreach (var e in g[v])
{
var (next, capacity, _) = edges[e];
if (capacity == 0 || depths[next] >= 0) continue;
depths[next] = w;
q.Enqueue(next);
}
}
Depths = depths;
}
long Flow(int v, int t, long f)
{
if (v == t) return f;
var (az, depths, edges) = (G[v], Depths, Edges);
var (ac, depth) = (az.Count, depths[v]);
for (ref var i = ref Iter[v]; i < ac; i++)
{
var e = az[i];
var (next, capacity, reverse) = edges[e];
if (capacity == 0 || depths[next] <= depth) continue;
var d = Flow(next, t, Math.Min(f, capacity));
if (d == 0) continue;
edges[e] = (next, capacity - d, reverse);
edges[reverse] = (v, edges[reverse].capacity + d, e);
return d;
}
return 0;
}
public List<(int edgeIndex, int ab, int ad)> MinCutEdges(int start)
{
var reachable = new HashSet<int>{ start };
var q = new Queue<int>();
q.Enqueue(start);
while (q.Count > 0)
{
var v = q.Dequeue();
foreach (var edgeIndex in G[v])
{
var edge = Edges[edgeIndex];
if (edge.capacity == 0) continue;
var next = edge.next;
if (reachable.Contains(next)) continue;
reachable.Add(next);
q.Enqueue(next);
}
}
var res = new List<(int, int, int)>();
for (var i = 0; i < Edges.Count; i += 2)
{
var ad = Edges[i].next;
var ab = Edges[i + 1].next;
if (reachable.Contains(ab) ^ reachable.Contains(ad)) res.Add((i, ab, ad));
}
return res;
}
}