/// <summary>
        /// Resultant of this polynomial with <c>x^n-1 mod p</c>.
        /// </summary>
        /// 
        /// <param name="P">P value</param>
        /// 
        /// <returns>Returns <c>(rho, res)</c> satisfying <c>res = rho*this + t*(x^n-1) mod p</c> for some integer <c>t</c>.</returns>
        public ModularResultant Resultant(int P)
        {
            // Add a coefficient as the following operations involve polynomials of degree deg(f)+1
            int[] fcoeffs = Coeffs.CopyOf(Coeffs.Length + 1);
            IntegerPolynomial f = new IntegerPolynomial(fcoeffs);
            int N = fcoeffs.Length;

            IntegerPolynomial a = new IntegerPolynomial(N);
            a.Coeffs[0] = -1;
            a.Coeffs[N - 1] = 1;
            IntegerPolynomial b = new IntegerPolynomial(f.Coeffs);
            IntegerPolynomial v1 = new IntegerPolynomial(N);
            IntegerPolynomial v2 = new IntegerPolynomial(N);
            v2.Coeffs[0] = 1;
            int da = N - 1;
            int db = b.Degree();
            int ta = da;
            int c = 0;
            int r = 1;

            while (db > 0)
            {
                c = Invert(b.Coeffs[db], P);
                c = (c * a.Coeffs[da]) % P;
                a.MultShiftSub(b, c, da - db, P);
                v1.MultShiftSub(v2, c, da - db, P);
                da = a.Degree();

                if (da < db)
                {
                    r *= Pow(b.Coeffs[db], ta - da, P);
                    r %= P;

                    if (ta % 2 == 1 && db % 2 == 1)
                        r = (-r) % P;

                    IntegerPolynomial temp = a;
                    a = b;
                    b = temp;
                    int tempdeg = da;
                    da = db;
                    temp = v1;
                    v1 = v2;
                    v2 = temp;
                    ta = db;
                    db = tempdeg;
                }
            }

            r *= Pow(b.Coeffs[0], da, P);
            r %= P;
            c = Invert(b.Coeffs[0], P);
            v2.Multiply(c);
            v2.Mod(P);
            v2.Multiply(r);
            v2.Mod(P);

            // drop the highest coefficient so #coeffs matches the original input
            v2.Coeffs = v2.Coeffs.CopyOf(v2.Coeffs.Length - 1);
            return new ModularResultant(new BigIntPolynomial(v2), BigInteger.ValueOf(r), BigInteger.ValueOf(P));
        }