AtCoderのABC    次のABCの問題へ    前のABCの問題へ

ABC259-E LCM on Whiteboard


問題へのリンク


C#のソース

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static string InputPattern = "InputX";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("4");
            WillReturn.Add("1");
            WillReturn.Add("7 2");
            WillReturn.Add("2");
            WillReturn.Add("2 2");
            WillReturn.Add("5 1");
            WillReturn.Add("1");
            WillReturn.Add("5 1");
            WillReturn.Add("2");
            WillReturn.Add("2 1");
            WillReturn.Add("7 1");
            //3
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("1");
            WillReturn.Add("1");
            WillReturn.Add("998244353 1000000000");
            //1
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();

        int[] wkArr = { };
        Action<string> SplitAct = pStr =>
            wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();

        // 素因数ごとの乗数のDictのList
        var PrimeProdDictList = new List<Dictionary<long, long>>();

        int CurrInd = 1;
        while (CurrInd <= InputList.Count - 1) {
            int TakeCnt = int.Parse(InputList[CurrInd]);

            var PrimeProdDict = new Dictionary<long, long>();
            foreach (string EachStr in InputList.Skip(CurrInd + 1).Take(TakeCnt)) {
                SplitAct(EachStr);

                long Prime = wkArr[0];
                long Jyousuu = wkArr[1];
                PrimeProdDict[Prime] = Jyousuu;
            }
            PrimeProdDictList.Add(PrimeProdDict);
            CurrInd += TakeCnt + 1;
        }

        // 素数ごとの乗数のList
        var PrimeProdListDict = new Dictionary<long, List<long>>();
        foreach (Dictionary<long, long> EachPrimeProdDict in PrimeProdDictList) {
            foreach (var EachPair in EachPrimeProdDict) {
                if (PrimeProdListDict.ContainsKey(EachPair.Key) == false) {
                    PrimeProdListDict[EachPair.Key] = new List<long>();
                }
                PrimeProdListDict[EachPair.Key].Add(EachPair.Value);
            }
        }

        // 降順にソートしておく
        foreach (var EachPair in PrimeProdListDict) {
            PrimeProdListDict[EachPair.Key].Sort((A, B) => B.CompareTo(A));
        }

        // 単独Maxを持つ行の数
        long Cnt1 = 0;

        // 単独Maxを持たない行の数
        long Cnt2 = 0;

        foreach (Dictionary<long, long> EachPrimeProdDict in PrimeProdDictList) {
            bool HasOnlyMax = false;
            foreach (var EachPair in EachPrimeProdDict) {
                if (PrimeProdListDict[EachPair.Key][0] > EachPair.Value) {
                    continue;
                }
                if (PrimeProdListDict[EachPair.Key].Count == 1) {
                    HasOnlyMax = true;
                    break;
                }
                if (PrimeProdListDict[EachPair.Key][0] > PrimeProdListDict[EachPair.Key][1]) {
                    HasOnlyMax = true;
                    break;
                }
            }
            if (HasOnlyMax) {
                Cnt1++;
            }
            else {
                Cnt2++;
            }
        }

        long Answer = Cnt1 + Math.Sign(Cnt2);
        Console.WriteLine(Answer);
    }
}


解説

LCMは、素因数の乗数の最大値の積
で表現することができます。

たとえば
2の30乗 * 3の5乗 * 5の7乗 * 7の3乗 と
2の10乗 * 3の2乗 * 5の9乗 * 7の7乗 のLCMは
2の30乗 * 3の5乗 * 5の9乗 * 7の7乗 です。

このことをふまえて、
素因数ごとの単独Maxを持つ行の数と
素因数ごとの単独Maxを持たない行の数を集計すれば
解が分かります。