题意简述
一个三角形如图所示变化。初始状态(第0个状态)是一个大三角形,然后每一个三角形都会被4等分,分完就是下一个状态。求第nnn(nnn的范围是101810^{18}1018!!!)个状态中有多少个尖角朝上的三角形。对109+710^9+7109+7取模。
数据
输入
2
输出
10
思路
设第iii个状态中有a[i]a[i]a[i]个朝上的,b[i]b[i]b[i]个朝下的。
首先每次4等分,三角形总数应该是不断×4\times 4×4的。所以a[i]+b[i]=4ia[i]+b[i]=4^ia[i]+b[i]=4i
我们发现,上一个状态中如果有一个朝下的,4等分之后会变成3个朝下的+1个朝上的。如果有一个朝上的,4等分之后会变成3个朝上的+1个朝下的。所以,我们珂以得到:
a[i]=3a[i−1]+b[i−1]b[i]=3b[i−1]+a[i−1] a[i]=3a[i-1]+b[i-1]\\ b[i]=3b[i-1]+a[i-1]\\ a[i]=3a[i−1]+b[i−1]b[i]=3b[i−1]+a[i−1]
这个式子有什么规律呢。。。
好像没有。
我们会想,如果知道a[i]+b[i]a[i]+b[i]a[i]+b[i],那么只要知道a[i]−b[i]a[i]-b[i]a[i]−b[i]就珂以直接求出a[i]a[i]a[i]和b[i]b[i]b[i]了。
那么我们减减试试吧。。。
a[i]−b[i]=3(a[i−1]−b[i−1])+(b[i−1]−a[i−1])=2(a[i−1]−b[i−1])a[i]-b[i]=3(a[i-1]-b[i-1])+(b[i-1]-a[i-1])=2(a[i-1]-b[i-1])a[i]−b[i]=3(a[i−1]−b[i−1])+(b[i−1]−a[i−1])=2(a[i−1]−b[i−1])
显然,当i=1i=1i=1时,a[i]=1,b[i]=0a[i]=1,b[i]=0a[i]=1,b[i]=0
设f(x)=a[x]−b[x]f(x)=a[x]-b[x]f(x)=a[x]−b[x],那么由上面的式子得
f(1)=1f(x)=2f(x−1)
f(1)=1\\
f(x)=2f(x-1)
f(1)=1f(x)=2f(x−1)
易得f(x)=2xf(x)=2^{x}f(x)=2x。
故a[i]−b[i]=2xa[i]-b[i]=2^xa[i]−b[i]=2x
所以,a[i]=a[i]+b[i]+a[i]−b[i]2=4n−2n2=22n−1+2n−1a[i]=\frac{a[i]+b[i]+a[i]-b[i]}{2}=\frac{4^n-2^n}{2}=2^{2n-1}+2^{n-1}a[i]=2a[i]+b[i]+a[i]−b[i]=24n−2n=22n−1+2n−1。
打快速幂就珂以了。
代码:
#include<bits/stdc++.h>
#define int long long
#define mod 1000000007
using namespace std;
int p2(int p,int m)//快速求2的幂
{
int a=2;
int r=1;
while(p)
{
if (p&1) r=r*a%m;
a=a*a%m,p>>=1;
}
return r;
}
int n;
void Solve()
{
if (n==0)//特判这个!!!
{
puts("1");
return;
}
printf("%I64d\n",(p2(2*n-1,mod)+p2(n-1,mod))%mod);
}
main()
{
scanf("%I64d",&n);
Solve();
return 0;
}