• 51nod求助


    求助dalao们,51nod1170实在是不会了,有没有大佬讲一下,有兴趣的可以告诉我,我提供AC代码。

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Numerics;
    
    namespace Problem51Nod
    {
        class Program
        {
            public static void Main(String[] args)
            {
                //BigInteger m = BigInteger.Pow(5, 143) - 1;
                //BigInteger n = BigInteger.Pow(2, 331) + 1;
                //int k = 100;
                BigInteger m = BigInteger.Parse(Console.ReadLine());
                BigInteger n = BigInteger.Parse(Console.ReadLine());
                int k = Convert.ToInt32(Console.ReadLine());
    
                //Stopwatch timer = new Stopwatch();
                //timer.Start();
                Console.WriteLine(Cmn(m, n, k));
                //timer.Stop();
                //Console.WriteLine(timer.Elapsed);
            }
    
            static BigInteger[][] PowerTable = new BigInteger[6][];
            static List<BigInteger[][]>[] PreTable = new List<BigInteger[][]>[6];
            static BigInteger[,] CMatrix;
    
            static void InitCMatrix(int l)
            {
                CMatrix = new BigInteger[l + 1, l + 1];
                for (int i = 0; i <= l; i++)
                    CMatrix[i, 0] = CMatrix[i, i] = 1;
    
                for (int i = 2; i <= l; i++)
                    for (int j = 1; j * 2 <= i; j++)
                        CMatrix[i, j] = CMatrix[i, i - j] = CMatrix[i - 1, j - 1] + CMatrix[i - 1, j];
            }
    
            static void InitPowerTab(int l, int p)
            {
                PowerTable[p] = new BigInteger[l + 1];
                PowerTable[p][0] = 1;
    
                for (int j = 1; j < PowerTable[p].Length; j++)
                    PowerTable[p][j] = PowerTable[p][j - 1] * p;
            }
    
            static void InitData(int l, BigInteger max, int p)
            {
                PreTable[p] = new List<BigInteger[][]>();
                BigInteger[] pre = MulTo(l, p);
                BigInteger[,] cMatrix = new BigInteger[l + 1, l + 1];
    
                for (int i = 0; i <= l; i++)
                    for (int j = 0; j <= i; j++)
                        cMatrix[i, j] = CMatrix[i, j];
    
                int power = 1;
                for (BigInteger i = p; i <= max; i *= p)
                {
                    BigInteger[][] cTable = new BigInteger[p - 1][];
                    cTable[0] = pre;
                    for (int j = 1; j < p; j++)
                    {
                        BigInteger[] next = ReplaceWith(cTable[0], i * j % PowerTable[p][l], l, p, cMatrix);
    
                        if (j < p - 1)
                            cTable[j] = MulMod(cTable[j - 1], next, l, p);
                        else
                            pre = MulMod(cTable[j - 1], next, l, p);
                    }
    
                    PreTable[p].Add(cTable);
                    power++;
                }
            }
    
            static BigInteger Cmn(BigInteger m, BigInteger n, int l)
            {
                InitCMatrix(l);
                InitPowerTab(l, 5);
                InitPowerTab(l, 2);
                BigInteger up5 = CalP(m, n, 5, l);
                BigInteger up2 = CalP(m, n, 2, l);
                BigInteger mod = ((up5 - up2) + PowerTable[5][l]) % PowerTable[5][l];
                mod = IMod(PowerTable[2][l], mod, PowerTable[5][l]) * PowerTable[2][l] + up2;
                return mod;
            }
    
            static BigInteger CalP(BigInteger m, BigInteger n, int p, int l)
            {
                BigInteger count = Count(m, p) - Count(n, p) - Count(m - n, p);
                if (count > l) return 0;
                InitData(l, m, p);
                BigInteger up = Cal(m, p, l) * PowerTable[p][(int)count];
                BigInteger down = Cal(n, p, l);
                down *= Cal(m - n, p, l);
                down %= PowerTable[p][l];
                up = IMod(down, up, PowerTable[p][l]);
                return up;
            }
    
            static BigInteger Count(BigInteger v, BigInteger mod)
            {
                BigInteger count = 0;
    
                while (v > 0)
                {
                    v /= mod;
                    count += v;
                }
    
                return count;
            }
    
            static List<BigInteger> Values = new List<BigInteger>();
            static List<int> Mods = new List<int>();
    
            static BigInteger Cal(BigInteger nums, int p, int l)
            {
                BigInteger numsBak = nums;
                Values.Clear();
                Mods.Clear();
    
                while (numsBak > 0)
                {
                    Values.Add(numsBak);
                    Mods.Add((int)(numsBak % p));
                    numsBak /= p;
                }
    
                BigInteger result = 1;
    
                for (int i = 0; i < Values.Count; i++)
                {
                    result *= CalSingle(i, p, l);
                    result %= PowerTable[p][l];
                }
    
                return result;
            }
    
            static BigInteger CalSingle(int cIndex, int p, int l)
            {
                int len = Mods[cIndex];
                BigInteger sum = 0, last = (Values[cIndex] - len) % PowerTable[p][l];
                BigInteger[] pre = new BigInteger[] { 1 };
                BigInteger result = 1;
                cIndex++;
    
                for (int i = Mods.Count - 1; i >= cIndex; i--)
                {
                    int index = Mods[i];
    
                    if (index > 0)
                    {
                        BigInteger modValue = 1, current = 0;
                        foreach (var item in PreTable[p][i - cIndex][index - 1])
                        {
                            if (item != 0)
                                current = (current + modValue * item) % PowerTable[p][l];
    
                            if (sum == 0 || modValue == 0)
                                break;
    
                            modValue = modValue * sum % PowerTable[p][l];
                        }
    
                        if (i - cIndex + 1 <= l)
                            sum = (sum + index * PowerTable[p][i - cIndex + 1]) % PowerTable[p][l];
    
                        result = (result * current) % PowerTable[p][l];
                    }
                }
    
                for (int i = 1; i <= len; i++)
                {
                    if (i % p == 0)
                        continue;
    
                    result *= last + i;
                    result %= PowerTable[p][l];
                }
    
                return result;
            }
    
            static BigInteger[] MulTo(int l, int p)
            {
                BigInteger[] result = new BigInteger[] { 1 };
    
                for (BigInteger i = 1; i < p; i++)
                {
                    if (i % p == 0)
                        continue;
    
                    BigInteger[] b = new BigInteger[] { i, 1 };
                    result = MulMod(result, b, l, p);
                }
    
                return result;
            }
    
            static BigInteger[] MulMod(BigInteger[] a, BigInteger[] b, int l, int p)
            {
                int len = Math.Min(l + 1, a.Length + b.Length - 1);
                BigInteger[] result = new BigInteger[len];
    
                for (int i = 0; i < Math.Min(a.Length, l + 1); i++)
                {
                    if (a[i] == 0)
                        continue;
    
                    int upper = Math.Min(b.Length, l - i + 1);
                    for (int j = 0; j < upper; j++)
                        result[i + j] += a[i] * b[j];
                }
    
                int last = 0;
    
                for (int i = 0; i < result.Length; i++)
                {
                    result[i] %= PowerTable[p][l - i];
                    if (result[i] > 0)
                        last = i + 1;
                }
    
                if (last < result.Length)
                    Array.Resize(ref result, last);
    
                return result;
            }
    
            //2次方算法,考虑大数是3次方 除以大进制的常数
            static BigInteger[] ReplaceWith(BigInteger[] source, BigInteger into, int l, int p, BigInteger[,] cMatrix)
            {
                int len = source.Length;
                len = Math.Min(len, l + 1);
                BigInteger[] result = new BigInteger[len];
                BigInteger[] power = new BigInteger[len];
                power[0] = 1;
    
                for (int i = 1; i < len; i++)
                    power[i] = power[i - 1] * into % PowerTable[p][l];
    
                for (int i = 0; i < len; i++)
                {
                    if (source[i] == 0)
                        continue;
    
                    for (int j = 0; j <= i; j++)
                    {
                        if (power[i] == 0) continue;
                        var tmp = power[i - j] * source[i] % PowerTable[p][l - j];
                        if (tmp == 0) continue;
                        result[j] += tmp * cMatrix[i, j];
                    }
                }
    
                for (int i = 0; i < result.Length; i++)
                    result[i] %= PowerTable[p][l - i];
    
                return result;
            }
    
            public static BigInteger EuclidExtend(BigInteger X, BigInteger Y, out BigInteger A, out BigInteger B)
            {
                if (Y == 0) { A = 1; B = 0; return X; }
                BigInteger quotient = X / Y;
                BigInteger gcd = EuclidExtend(Y, X - Y * quotient, out A, out B);
                BigInteger Temp = A; A = B; B = Temp - quotient * A;
                return gcd;
            }
    
            public static bool Linear(BigInteger X, BigInteger Y, BigInteger N, out BigInteger xResult, out BigInteger yResult)
            {
                BigInteger gcd = EuclidExtend(X, Y, out xResult, out yResult);
                if (N % gcd != 0) { return false; }
                xResult = xResult * N / gcd % Y;
                xResult = xResult >= 0 ? xResult : xResult + Y;
                yResult = yResult * N / gcd % X;
                yResult = yResult <= 0 ? yResult : yResult - X;
                return true;
            }
    
            public static BigInteger IMod(BigInteger A, BigInteger B, BigInteger P)
            {
                BigInteger x, y;
                Linear(A, P, B, out x, out y);
                return x;
            }
        }
    }
    View Code
  • 相关阅读:
    HTML音频/视频DOM 参考手册
    HTML5 应用程序缓存 和 视频
    HTML 5 新的Input类型
    快速开发平台消息通知中心之短信发送
    设计模式之单例设计模式
    反射
    多线程之线程安全
    01-sql优化及索引
    多线程之线程状态
    shell/linux定时清理日志文件
  • 原文地址:https://www.cnblogs.com/Amphetamine/p/8515378.html
Copyright © 2020-2023  润新知