牛客网暑期ACM多校训练营(第八场)G Counting regions(欧拉示性数公式)

链接:https://www.nowcoder.com/acm/contest/146/G
来源:牛客网
 

题目描述

Niuniu likes mathematics. He also likes drawing pictures. One day, he was trying to draw a regular polygon with n vertices. He connected every pair of the vertices by a straight line as well. He counted the number of regions inside the polygon after he completed his picture. He was wondering how to calculate the number of regions without the picture. Can you calculate the number of regions modulo 1000000007? It is guaranteed that n is odd.

输入描述:

The only line contains one odd number n(3 ≤ n ≤ 1000000000), which is the number of vertices.

输出描述:

Print a single line with one number, which is the answer modulo 1000000007.

示例1

输入

复制

3

输出

复制

1

示例2

输入

复制

5

输出

复制

11

备注:

 

The following picture shows the picture which is drawn by Niuniu when n=5. Note that no three diagonals share a point when n is odd.

题意:正多边形边两两相连,问把多边形分割成了几块

思路:自己做的时候是找规律做的,几何画板画出来数啊数,赛后看题解这里可以用欧拉示性数公式,有个视频讲的不错【官方中配】分圆问题,诡异的数列规律:解答篇 ,利用V-E+F=2,可以很快求得,V是顶点数,E是边数,F是区域块数(包括外围),顶点数,可以通过圆上任意四点确定一个交点的方法来求内部交点数,V=n+C_{n}^{4} 。而x条线交于y点,线段数是x+2*y,所以E=C_{n}^{2}+2*C_{n}^{4}。F=E-V+2,再减去最外的区域1,就是答案。题中n为奇数,所以不存在三条直线交于一点的情况(这是公式成立的前提)。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll mo(ll a,ll pp){
    if(a>=0&&a<pp)return a;
    a%=pp;
    if(a<0)a+=pp;
    return a;
}
ll powmod(ll a,ll b,ll pp){
    ll ans=1;
    for(;b;b>>=1,a=mo(a*a,pp)){
        if(b&1)ans=mo(ans*a,pp);
    }
    return ans;
}

ll inv1(ll b){
	return powmod(b,mod-2,mod);
}
ll inv2(ll a){
	if(a==1)return 1;
	return inv2(mod%a)*inv2(mod-mod/a)%mod;
}

int main(){
	ll n;
	scanf("%lld",&n);
	ll x=n*(n-1)%mod*inv1(2)%mod;
	ll y=n*(n-1)%mod*(n-2)%mod*(n-3)%mod*inv1(24)%mod;
	printf("%lld\n",(x+y-n+1+mod)%mod);
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/yz467796454/article/details/81608928