昨晚睡觉躺床上突然YY出来这么个做法……今天试验了下还真可行,虽然和设想有些出入……
VC++的空间占用比GNU小,时间嘛因为一个不严谨的错误结果进了15ms,至于代码长度……还算比较短吧,如果不粘思路部分
直接粘代码……
/*
用s[i=1..10^18,0..1,0..1]表示当前有i位,0/1表示有偶数/奇数个7,另一对0/1表示9
s[i,0,0]=s[i-1,0,0]*3+s[i-1,0,1]+s[i-1,1,0] (1)
s[i,1,1]=s[i-1,1,1]*3+s[i-1,0,1]+s[i-1,1,0] (2)
s[i,1,0]=s[i-1,1,0]*3+s[i-1,0,0]+s[i-1,1,0] (3)
s[i,0,1]=s[i-1,0,1]*3+s[i-1,0,0]+s[i-1,1,1] (4)
初值的话s[1,0,1]=s[1,1,0]=1; s[1,0,0]=3; s[1,1,1]=0
首先(1)+(2)/(3)+(4)得到按79奇偶性相同/相异划分的两个递推式
s[i,0,0]+s[i,1,1]=(s[i-1,0,0]+s[i-1,1,1])*3+(s[i-1,1,0]+s[i-1,0,1])*2
s[i,1,0]+s[i,0,1]=(s[i-1,1,0]+s[i-1,0,1])*3+(s[i-1,0,0]+s[i-1,1,1])*2
用a[i,0]表示79奇偶性相同的情况,a[i,1]表示不同的
a[i,0]=a[i-1,0]*3+a[i-1,1]*2
a[i,1]=a[i-1,1]*3+a[i-1,0]*2
初值a[1,0]=3; a[1,1]=2
相加可以得到总情况数5^n不过这是废话一眼就能看出来,做差
a[i,0]-a[i,1]=a[i-1,0]*(3-2)+a[i-1,1]*(2-3)=a[i-1,0]-a[i-1,1]
发现79奇偶性相同和不同情况之差总是定值,也就是1
这样直线得到了a[n,0]=s[n,0,0]+s[n,1,1]=(5^n+1)/2 (5)
再用a[n,0]回推s[n,0,0],考虑(1)-(2)
s[i,0,0]-s[i,1,1]=3*(s[i-1,0,0]-s[i-1,1,1])
等比数列,那么s[n,0,0]-s[n,1,1]=3^n (6)
(5)+(6)就得到了
2ans=(5^n+1)/2+3^n
套公式的时候注意下奇偶性就可以了,最后加起来还要再模一下
应该有排列组合一步到位的思路吧?
*/
#include <cstdio>
using namespace std;
#define ll long long
#define MOD 1000000007
int T; ll n;
ll shr(ll x) {if (x&1) return ((x+MOD)>>1); return (x>>1);}
ll qmod(ll a, ll b) {
ll t=1;
for (; b; b>>=1,a=a*a%MOD) if (b&1) t=t*a%MOD;
return t;
}
int main() {
int T; scanf("%d",&T);
while (T--) {
scanf("%I64d",&n);
printf("%I64d\n",(shr(qmod(3,n)+shr(qmod(5,n)+1)))%MOD);
}
return 0;
}
嗯……至于为啥要新写一段呢,纯粹是为了凑每月4篇……我太懒了……