1. 程式人生 > >ACM-ICPC 2017 Asia Urumqi D. Fence Building

ACM-ICPC 2017 Asia Urumqi D. 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.

Input

The first line contains an integer 1 \le T \le 1000001≤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 \le T \le 10^51≤T≤105 and 1 \le n \le 10^{18}1≤n≤1018.

Output

For each test case, you should output a line ”Case #ii: ans” where ii is the test caseS number, starting from 11and ans is the remainder of the maximum number of cows farmer John can feed when divided by 10^9 + 7109+7.

樣例輸入複製

3
1
3
5

樣例輸出複製

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

題目來源

題意:在一個圓的圓弧上找n個點,兩兩之間連線,問你能形成多少個封閉的區域。

題解:太弱了,寫出一個長長的公式但是不知道如何化簡。。。

現在總結一下。QAQ

這種平面或立體中的點,邊,面有關係的。具體出門左轉百度“尤拉定理 幾何”。簡單說就是:點 - 邊 + 面 = 2

然後這道題讓求面,我們只需要求點和邊。

我是先把外面的圓先扔掉不看,只看裡面的多邊形。最後加上n-1即可。

在一個n邊形中我們會發現,任取四個不同的點1,2,3,4。我們把(1,3)和(2,4)連邊,一定會相交於一點,再算上多邊形本身的n個點,一共 n + C(4,n)個點。

邊數比較難想,首先我們把n個點,兩兩連邊,這一共有C(2,n)條邊,然後我們再對於任選的四個不同的點,我們會發現把(1,3)和(2,4)連邊,一定會相交於一點,並且多出兩條邊(原來的邊被切開了)。可以手畫一下。然後邊數有C(2,n)+2*(4,n)。

所以化簡後答案為C(2,n)+C(4,n)+1

因為有模數且是多組資料,所以對於上面這個,我們預處理出2和24的逆元即可得答案。

#include<bits/stdc++.h>
#define LL long long
#define MOD 1000000007
using namespace std;
LL read()
{
	LL s=0,fh=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
	return s*fh;
}
LL ksm(LL bb,LL pp,LL kk)
{
	LL s=1LL;
	while(pp>0LL)
	{
		if(pp%2LL!=0LL)s=(s*bb)%kk;
		pp/=2LL;
		bb=(bb*bb)%kk;
	}
	return s;
}
int main()
{
	LL T,ny2,ny24,n,a1,a2,case1=0LL;
	T=read();
	ny2=ksm(2LL,MOD-2LL,MOD);ny24=ksm(24LL,MOD-2LL,MOD);
	while(T--)
	{
		n=read();
		a1=((((n%MOD)*((n-1LL)%MOD))%MOD)*ny2)%MOD;
		a2=(((n%MOD)*((n-1LL)%MOD)%MOD)*(((n-2LL)%MOD)*((n-3LL)%MOD)%MOD))%MOD;
		a2=(a2*ny24)%MOD;
		printf("Case #%lld: %lld\n",++case1,((a1+a2+1LL)%MOD+MOD)%MOD);
	}
	return 0;
}