Exemple #1
0
        public void Solve()
        {
            var n    = ri;
            var a    = Enumerate(n, x => rl);
            var mf   = new MaxFlow(2 * n + 2);
            var src  = 2 * n;
            var sink = src + 1;
            var ans  = 0L;

            for (int i = 1; i <= n; i++)
            {
                var v = a[i - 1];
                if (v < 0)
                {
                    //???????
                    mf.AddDirectedEdge(n + i - 1, sink, -v);
                }
                else
                {
                    ans += v;
                    //?????
                    mf.AddDirectedEdge(src, i - 1, v);
                }
                mf.AddDirectedEdge(i - 1, i + n - 1, INF);
                for (int j = 2 * i; j <= n; j += i)
                {
                    // j ??????i ?????????
                    mf.AddDirectedEdge(j - 1, i - 1 + n, INF);
                }
            }
            var val = mf.Execute(src, sink);

            Debug.WriteLine(val);
            Console.WriteLine(ans - val);
        }
Exemple #2
0
        public void Solve()
        {
            var       n   = ri;
            const int MAX = 10000005;
            var       a   = new int[MAX];
            var       b   = new int[MAX];

            foreach (var x in sc.Integer(n))
            {
                a[x] = 1;
            }
            for (int i = 0; i < MAX - 1; i++)
            {
                b[i] = a[i + 1] ^ a[i];
            }
            var xs = Enumerate(2, x => new List <int>());

            for (int i = 0; i < MAX; i++)
            {
                if (b[i] == 1)
                {
                    xs[i % 2].Add(i);
                }
            }


            var isprime = MathEx.Sieve(10000005);

            isprime[2] = false;

            var m = xs[0].Count + xs[1].Count;

            Debug.WriteLine(m);
            Debug.WriteLine(xs[0].AsJoinedString());
            Debug.WriteLine(xs[1].AsJoinedString());
            var G = new MaxFlow(m + 2);

            for (int i = 0; i < xs[0].Count; i++)
            {
                for (int j = 0; j < xs[1].Count; j++)
                {
                    if (isprime[Math.Abs(xs[0][i] - xs[1][j])])
                    {
                        G.AddDirectedEdge(i, xs[0].Count + j, 1);
                    }
                }
            }
            var f = m;
            var t = m + 1;

            for (int i = 0; i < xs[0].Count; i++)
            {
                G.AddDirectedEdge(f, i, 1);
            }
            for (int i = 0; i < xs[1].Count; i++)
            {
                G.AddDirectedEdge(xs[0].Count + i, t, 1);
            }
            var mf  = G.Execute(f, t);
            var ans = mf;
            var u   = xs[0].Count - mf;
            var v   = xs[1].Count - mf;

            ans += 2 * (u / 2);
            ans += 2 * (v / 2);
            if (u % 2 == 1)
            {
                ans += 3;
            }
            IO.Printer.Out.WriteLine(ans);
        }