upc 5215: Fence Building(欧拉定理/推导+OEIS)

5215: Fence Building

题目描述

Farmer John owns a farm. He first builds a circle fence. Then, he will choose n points and build some straight fences connecting them. Next, he will feed a cow in each region so that cows cannot play with each other without breaking the fences. In order to feed more cows, he also wants to have as many regions as possible. However, he is busy building fences now, so he needs your help to determine what is the maximum number of cows he can feed if he chooses these n points properly.

输入

The first line contains an integer 1 ≤ T ≤ 100000, the number of test cases. For each test case, there is one line that contains an integer n. It is guaranteed that 1 ≤ T ≤ 105 and 1 ≤ n ≤ 1018 .

输出

For each test case, you should output a line ”Case #i: ans” where i is the test case number, starting from 1 and ans is the remainder of the maximum number of cows farmer John can feed when divided by 109 + 7.

样例输入

3
1
3
5

样例输出

Case #1: 1
Case #2: 4
Case #3: 16

来源/分类

ICPC2017 Urumqi

参考链接:https://blog.csdn.net/tianwei0822/article/details/8127


题意:

给你一个圆圈,让你在圆上给你n个点,让你通过这n个点连线来划分区域,请问最大的划分的区域为多少???

题解:

紫书336页UVA10213

首先给出一个我自己推公式的做法,自己推出来的!!!并不靠谱。

只能推出前10组吧。结合OEIS来找到对应的公式罢了。

正解就应该是:欧拉定理,本来我是不知道的,后来通过看别人的分析大概知道是什么一回事吧。

首先给出自己的方法吧,

我画出n=5,n=6两个图给大家热身一下。

首先大家要知道,一个区域的划分:F=V+E.(F是划分的区域,V是交点数,E是边的数量)

一个直线划分,主要是找出它的交点,区域=交点数+1.

当n=5时:

a[5]=a[4]+2+(2+2)+2   两个新的区域+(各条边的交点数)+边数


当n=6时:

a[6]=a[5]+2+(3+4+3)+3   两个新的区域+(各条边的交点数)+边数

通过几组示例类比得到,

a[7]=a[6]+2+(4+6+6+4)+4

a[8]=a[7]+2+(5+8+9+8+5)+5

a[9]=a[8]+2+(6+10+12+12+10+6)+6

a[10]=a[9]+2+(7+12+15+16+15+12+7)+7

后来通过OEIS来找到答案。

然而答案应该是通过欧拉公式推导出来的。

欧拉做了很多方面的研究,而欧拉定理和欧拉公式还是傻傻分不清楚。

我给大家找来了一个课件,讲的就是欧拉公式从多面体到平面的一个拓展。

了解一下:欧拉公式:

https://wenku.baidu.com/view/a6a62645b307e87101f6968d.html?sxts=1535026638773

这个题的论文:

https://en.wikipedia.org/wiki/Dividing_a_circle_into_areas

提供论文的大佬博客:

http://www.cnblogs.com/AOQNRMGYXLMV/p/4192316.html


然后推公式吧,这里用到平面图的欧拉公式,V - E + F = 2,其中V表示顶点个数,E表示边的个数,F表示面的块数。

减去最外面的无限大的面,所求ans = E - V + 1

假设n≥4,从圆周上的一个点出发枚举一条对角线,左边有i个点,右边有n-2-i个点,将左右两边的点两两相连,就在这条对角线上得到个交点。每个交点被重复计算4次,再加上圆周上的n个点,所以

接下来E也很好计算,一条对角线有个交点,所以就有条边,而这里要注意,每条边是被重复计算2次的。再加上圆周被n个点分隔开的n条边和n个点相邻两点的连线有n条边,所以

然后再根据这两个公式

化简一下得到 


太有趣了这个题:

我先贴上代码:

等我自己手稿写好一定附上!!!

#include<bits/stdc++.h>
using namespace std;
const int N =1005;
typedef long long ll;
const ll mod=1e9+7;
ll qpow(ll a,ll b){
    ll ans=1;
    a%=mod;
    while(b){
        if(b&1){
            ans=ans*a%mod;
        }
        a=a*a%mod;
        b>>=1;
    }
    return ans%mod;
}
int t=1;
template <class T>
void read(T &x){
    x=0;int f=1;char c=getchar();
    for( ; !isdigit(c) ;c=getchar()){if(c=='-')f=-1;}
    for( ;  isdigit(c) ;c=getchar()){x=x*10+c-'0';}x*=f;
}
void solve(){
    ll n,ans;
    scanf("%lld",&n);
    ans=qpow(n,4);
    ans=(ans-(qpow(n,3)%mod)*6+6ll*mod)%mod;
    ans=(ans+(qpow(n,2)%mod)*23)%mod;
    ans=(ans-(n%mod)*18+18ll*mod)%mod;
    ans=(ans+24ll)%mod;
    ans=(ans*qpow(24,mod-2))%mod;
    printf("Case #%d: %lld\n",t,ans);
}
int main()
{
    int T;
    read(T);
    for(t=1;t<=T;t++){
        solve();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Z_sea/article/details/81953212
UPC
今日推荐