JZOJ 5878. 【NOIP2018提高組模擬9.22】電路圖 A
Description
nodgd 要畫一個電路圖。 這是一個很簡單的電路圖,所有的元件都是串聯關係,從整體來看就是一個環狀的結構。畫電路圖有很多要求,nodgd 為了畫得好看就又添加了一些 額外的要求。所有要求歸結起來有以下幾點: 1、這個環狀電路上有n個雙端電路元件(即每個電路元件有兩個連線導線的接頭),其中只有一個直流電源;為了本題方便,其他n − 1個元件都是一模一樣的電阻。 2、電流在電路圖中每經過一個元件,就必須拐一個90°的彎;沒有經過元件時不允許拐彎。參考右圖。
3、從電路圖整體上觀察,電流沿順時針方向流動,且電路不能自交。參考下圖。
4、如果一個符合題意的電路圖,可以通過整體旋轉一定的角度,再適當調整圖中導線的長度,得到另外一個符合題意的電路圖,則這兩個電路圖是相同的。參考下圖。
5、如果電路環路的內部存在一個點,使得它可以“看到”電路環路內部的所有位置,就認為這個圖是美觀的,反之是不美觀的。相同的電路圖不一定都美觀。參考下圖。
那麼問題來了,nodgd 想知道有多少種不同的電路圖,以及有多少種不同的美觀電路圖。由於兩個問題的答案都可能很大,請mod 1,000,000,007輸出結果。
Input
輸入檔案 A.in。 輸入檔案第一行包含一個正整數n,表示包含電源在內的電路元件的總數量。
Output
輸出檔案A.out。 輸出檔案第一行包含一個整數,表示不同的電路圖數量mod 1,000,000,007的結果。第二行包含一個整數,表示不同的美觀電路圖數量mod 1,000,000,007的結果。
Sample Input
【樣例1】 6 【樣例2&3】見下發檔案
Sample Output
【樣例1】 6 6
Data Constraint
對於 10%的資料,n = 12; 對於 30%的資料,n ≤ 24; 對於 60%的資料,n ≤ 5000; 對於 100%的資料,4 ≤ n ≤ 10^7,且n是個偶數。
Hint
【輸入輸出樣例 1 說明】 可以有如下幾種電路圖,電路圖數量是 6,所以輸出檔案第一行輸出一個整數 6; 容易發現,這 6 個電路圖都是美觀的電路圖,所以第二行也輸出一個整數 6。
Solution
-
結論題。
-
有一個元件就會拐彎一次,我們發現 右拐次數就等於左拐次數+4 ,因為要順時針拐一圈回來。
-
所以第一問的答案即為 ,即從 次拐彎中選 次左拐。
-
第二問的話我們發現不能連續兩次逆時針拐彎,不然就會形成一個不美觀的凹型。
-
所以我們把路徑分成四段,可以發現每段的拐彎數都是奇數。
-
問題轉化為將 拆分成 4 個奇數的方案數( 是偶數)。
-
我們先考慮將 拆成 4 個偶數怎麼做。將 個偶數排在一起(都小於 )。
-
選 3 個出來(相當於擋板),將間隔作為選擇的偶數(保證了和不會超過 )。
-
於是我們就可以得出方案書為 。
-
類比選 4 個奇數,我們將這四個奇數都加 1 ,則和為 。
-
於是方案數為
-
由於電源放在哪兒都可以,所以要乘 ;
-
又因為整體旋轉後相同的電路圖都是一樣的,所以要除以 4 。
-
故第二問最終答案為 。
Code
#include<cstdio>
using namespace std;
typedef long long LL;
const int N=1e7+5,mo=1e9+7;
int n;
int f[N];
inline int ksm(int x,int y)
{
int s=1;
while(y)
{
if(y&1) s=(LL)s*x%mo;
x=(LL)x*x%mo;
y>>=1;
}
return s;
}
inline int C(int x,int y)
{
return (LL)f[x]*ksm(f[y],mo-2)%mo*ksm(f[x-y],mo-2)%mo;
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d",&n);
for(int i=f[0]=1;i<=n;i++) f[i]=(LL)f[i-1]*i%mo;
printf("%d\n",C(n,n/2-2));
printf("%d",(LL)C(n/2+1,3)*n%mo*ksm(4,mo-2)%mo);
return 0;
}