[ Nowcoder Contest 167 #D ] 重蹈覆辙

\(1\times 2\)的矩形和面积为\(3\)\(L\)形去覆盖一个\(2\times N\) 的矩形,求方案数对\(10^4+7\)取模后的结果。

允许用于覆盖的图形旋转。两个方案不同当且仅当覆盖后形成的边界线至少有一处不同。

  • \(N\in [1,10^{100000}]\)

\(\\\)

\(Solution\)


神仙出题人神仙做法

\(f[i][0/1]\)表示当前处理到第 \(i\) 位,前面的列都已经填满,当前位置填满 \(/\) 剩一个没填的方案数。

转移分放什么讨论,注意横着并排两个长条的情况要直接计数,新放置一个 \(L\) 形有两种不同的方式:

\[\begin{align}f[i][0]=f[i-1][0]+f[i-1][1]+f[i-2][0]\end{align} \]

\[\begin{align}f[i][1]=2\times f[i-2][0]+f[i-1][1]\end{align} \]

把下面的式子带入\((3)\),有

\[\begin{align}f[i][0]=f[i-1][0]+f[i-2][0]+f[i-2][1]+2\times f[i-3][0]\end{align} \]

然后再把\((1)\)式中的\(i-1\)代入,有

\[f[i][0]=2\times f[i-1][0]+f[i-3][0] \]

于是可以矩阵快速幂了。复杂度\(\text O(log (10^{100000}))\),因为快速幂迭代的时候指数是\(N\)需要高精度所以会\(T\)

然后黑科技十进制快速幂:\(A^N=A^{\lfloor\frac{N}{10}\rfloor}A^{N\%10}\),显然指数部分就可以直接按照高精按位计算了。

还有神仙做法是找循环节,发现是模数\(-1\),打个表就好了......

\(\\\)

\(Code\)


#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define R register
#define mod 10007
#define gc getchar
using namespace std;
 
inline int rd(){
  int x=0; char c=gc();
  while(!isdigit(c)) c=gc();
  while(isdigit(c)){x=((x<<1)+(x<<3)+(c^48))%(mod-1);c=gc();}
  return x;
}
 
int n,f[mod]={1,1,2};
 
int main(){
  n=rd();
  for(R int i=3;i<=n;++i) f[i]=((f[i-1]*2)+f[i-3])%mod;
  printf("%d",f[n]);
  return 0;
}
posted @ 2018-10-08 09:43  SGCollin  阅读(213)  评论(0编辑  收藏  举报