UPC 组队训练 5215 Fence Building(欧拉示性数)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a17865569022/article/details/81913494

这里写图片描述
题意:给一个圆,圆上有N个点,N个点两两连成一条直线,问最多能把这个圆分成几部分。
根据欧拉示性数 常数2=V(点个数)+F(面个数)-E(边条数)。
链接:对欧式性数的解释
得到公式:F=C(n 2)+C(n,4)+1;
链接:对公式的证明
由于取模运算,有对除法的取模运算,需要用到逆元
(a + b) % p = (a%p + b%p) %p (对)
(a - b) % p = (a%p - b%p) %p (对)
(a * b) % p = (a%p * b%p) %p (对)
(a / b) % p = (a%p / b%p) %p (错)
链接:取模运算总结
最后Java大数运算AC,这里要将乘法拆开分部运算,否则Java会超时。

import java.util.*;
import java.math.*;
public class Main {

    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int t;
        t=in.nextInt();
        BigInteger n,a,b,sum,m,s,f,p,q,r;
        m=BigInteger.valueOf(1000000007);
        s=BigInteger.valueOf(2);
        f=BigInteger.valueOf(24);
        p=BigInteger.valueOf(1);
        r=BigInteger.valueOf(3);
        for(int i=1;i<=t;i++)
        {
            n=in.nextBigInteger();
            a=n.multiply(n.subtract(p));
            a=a.divide(s);
            b=n.multiply(n.subtract(p));
            b=b.multiply(n.subtract(s));
            b=b.multiply(n.subtract(r));
            b=b.divide(f);
            sum=a.add(b).add(p);
            BigInteger modd = sum.mod(m);
            System.out.print("Case #");
            System.out.print(i);
            System.out.print(": ");
            System.out.println(modd);
        }
    }  
}

猜你喜欢

转载自blog.csdn.net/a17865569022/article/details/81913494