1. 程式人生 > 實用技巧 >【題解】妞妞的三個盒子

【題解】妞妞的三個盒子

題目背景

妞妞在公園裡遊玩時撿到了很多小球,而且每個球都不一樣。妞妞找遍了全身只發現了 \(3\) 個一模一樣的盒子。她打算把這些小球都裝進盒子裡(盒子可以為空)。她想知道她總共有多少种放法。

問題描述

\(N\) 個不同的球放到3個相同的盒子裡,求放球的方案總數 \(M\) 。 結果可能很大,我們僅要求輸出 \(M\bmod K\)的結果。 現在,妞妞已經統計出了 \(N\le10\) 的所有情況。見下表:

N M
1 1
2 2
3 5
4 14
5 41
6 122
7 365
8 1094
9 3284
10 9842

輸入格式

兩個整數 \(N\) , \(K\)\(N\) 表示球的個數。

輸出格式

輸出僅包括一行,一個整數 \(M \bmod K\)

樣例

輸入樣例
11 10000
輸出樣例
9525

資料範圍與提示

對於 \(40\%\) 資料, \(10\le N\le10,000\) ; 對於 \(100\%\)資料, \(10\le N\le 10^9\)\(K\le100000\)

蒟蒻專屬——找規律!
小心翼翼地,把表格的第二欄乘 \(2\) ~

N M'
1 2
2 4
3 10
4 28
5 82
6 244
7 730
8 2188
9 6568
10 19684

再不動聲色,減一個 \(1\)~

N M''
1 1
2 3
3 9
4 27
5 81
6 243
7 729
8 2187
9 6567
10 19683

我們發現,\(M''=3^{N-1}\),而 \(M=(M''+1)\div2\) ,也就是說,\(M=(3^{N-1}+1)\div 2\) !
這不就好求了嘛。
可恨的是,這辣雞題目居然還要取模!
你說你出道題,別人好不容易把規律找出來了,你還讓別人重學數論!
(╯>皿<)╯((( ┷━━━┷ 掀桌

在無數次 \(BDFS\) 後,我們 \(search\) 到了下面這個公式:

\[(a\div b)\bmod m=(a\bmod(b\times m))\div b \]

那麼,我們可以得到:

\[M=((3^{N-1}+1)\bmod(2\times m))\div 2 \]

斯國一!那麼接下來。。。

Code
#include<cstdio>
typedef long long ll;
ll n,mod,ans;
ll ksm(ll ds,ll zs){
	ll ans=1;
	while(zs){
		if(zs&1)ans=ans*ds%mod;
		ds=ds*ds%mod;
		zs>>=1;
	}
	return ans;
}
int main(){
	freopen("bags.in","r",stdin);
	freopen("bags.out","w",stdout);
	scanf("%lld%lld",&n,&mod);
	mod<<=1;
	ans=ksm(3,n-1)%mod;
	printf("%lld",(((ans+1)%mod)>>1)%mod);
	return 0;
}

end.