예제 #1
0
파일: 4827831.cs 프로젝트: qifanyyy/CLCDSA
    void Solve()
    {
        var I = G;
        int V = I[0], E = I[1];
        var es = new int[E][];

        for (var i = 0; i < E; i++)
        {
            es[i] = G;
        }
        var uf  = new UnionFindTree(V);
        var ans = new long[E];
        var sum = V * (V - 1L) / 2;

        for (var i = E - 1; i >= 0; i--)
        {
            ans[i] = sum;
            int u = es[i][0] - 1, v = es[i][1] - 1;
            if (!uf.IsSameCategory(u, v))
            {
                sum -= uf.GetSize(u) * (long)uf.GetSize(v);
                uf.UniteCategory(u, v);
            }
        }
        for (var i = 0; i < E; i++)
        {
            WriteLine(ans[i]);
        }
    }
예제 #2
0
    static void Main()
    {
        SetOut(new StreamWriter(OpenStandardOutput())
        {
            AutoFlush = false
        });
        var I = G;
        int N = I[0], M = I[1];
        var uf = new UnionFindTree(N);

        for (var i = 0; i < M; i++)
        {
            I = G;
            int a = I[0] - 1, b = I[1] - 1;
            uf.Unite(a, b);
        }
        var Q  = int.Parse(ReadLine());
        var sb = new StringBuilder();

        while (Q-- > 0)
        {
            I = G;
            int x = I[0] - 1, y = I[1] - 1, z = I[2], l = 0, r = M + 1;
            while (l < r)
            {
                var t = (l + r) / 2;
                int p = uf.Find(t, x), q = uf.Find(t, y), s = p == q?uf.GetSize(t, p) : uf.GetSize(t, p) + uf.GetSize(t, q);

                if (s >= z)
                {
                    r = t;
                }
                else
                {
                    l = t + 1;
                }
            }
            sb.AppendLine(l.ToString());
        }
        Write(sb);
        Out.Flush();
    }
예제 #3
0
파일: 2049185.cs 프로젝트: qifanyyy/CLCDSA
    void Solve()
    {
        var I = G;

        N  = I[0];
        M  = I[1];
        es = new Tuple <int, int> [M];
        for (var i = 0; i < M; i++)
        {
            I     = G;
            es[i] = new Tuple <int, int>(I[0], I[1]);
        }
        Q  = F;
        qs = new Tuple <int, int, int> [Q];
        for (var i = 0; i < Q; i++)
        {
            I     = G;
            qs[i] = new Tuple <int, int, int>(I[0], I[1], I[2]);
        }
        {
            var i = 1;
            while (i < M)
            {
                i <<= 1;
            }
            var tmp = new Tuple <int, int> [i];
            for (var j = 0; j < M; j++)
            {
                tmp[j] = new Tuple <int, int>(es[j].Item1 - 1, es[j].Item2 - 1);
            }
            for (var j = M; j < i; j++)
            {
                tmp[j] = new Tuple <int, int>(0, 0);
            }
            es = tmp; M = i;
            for (var j = 0; j < Q; j++)
            {
                qs[j] = new Tuple <int, int, int>(qs[j].Item1 - 1, qs[j].Item2 - 1, qs[j].Item3);
            }
        }
        var log = MSB((uint)M);
        var seg = new List <int> [2 * M - 1];

        for (var i = 0; i < 2 * M - 1; i++)
        {
            seg[i] = new List <int>();
        }
        var node = 0;

        for (var i = 0; i < Q; i++)
        {
            seg[node].Add(i);
        }
        for (var i = 0; i < log; i++)
        {
            var uf  = new UnionFindTree(N);
            var mod = 1 << (log - i);
            var e   = 0;
            for (var j = mod >> 1; j < M; j += mod)
            {
                for (; e < j; e++)
                {
                    uf.UniteCategory(es[e].Item1, es[e].Item2);
                }
                foreach (var q in seg[node])
                {
                    int x = qs[q].Item1, y = qs[q].Item2, z = qs[q].Item3, w = 0;
                    if (uf.IsSameCategory(x, y))
                    {
                        w = uf.GetSize(x);
                    }
                    else
                    {
                        w = uf.GetSize(x) + uf.GetSize(y);
                    }
                    if (w >= z)
                    {
                        seg[2 * node + 1].Add(q);
                    }
                    else
                    {
                        seg[2 * node + 2].Add(q);
                    }
                }
                seg[node].Clear();
                node++;
            }
        }
        var ans = new int[Q];

        for (var i = M - 1; i < 2 * M - 1; i++)
        {
            foreach (var x in seg[i])
            {
                ans[x] = i - M + 1;
            }
        }
        for (var i = 0; i < Q; i++)
        {
            WriteLine(ans[i] + 1);
        }
    }