标签:printf pid 题目 names namespace line ble show class
神仙题,完全没想到。
朴素想法,我们开4*4的矩阵,分别记录\(\sqrt{2}\),\(\sqrt{3}\),\(\sqrt{6}\),\(1\)的系数,然后快速幂。
但是我们没法对系数取模,因此不能确定整数部分。
再分析一下,题目让我们求\((\sqrt{2} + \sqrt{3})^{2n}\),那不就是\((5 + 2\sqrt{6})^{n}\)吗,这成功减少了一个无理数,我们继续用刚才的方法。
虽然依旧不能算出答案,但是矩阵只要2*2了。
接下来就是我不会的东西了
考虑上面的矩阵,我们可以利用它来求得准确解\(a+b\sqrt{6}\),其中\(a\)可以准确知道,并在计算过程中取模
采用数学方法消去\(b\sqrt{6}\),我们构造\((5-2\sqrt{6})^n\),其准确值为\(a-b\sqrt{6}\)
\((5+2\sqrt{6})^n + (5-2\sqrt{6})^n = a+b\sqrt{6}+a-b\sqrt{6}=2a\)
因为\(0 < 5-2\sqrt{6} < 1\),所以\(0 < (5-2\sqrt{6})^n < 1\)
令\(t = (5-2\sqrt{6})^n\),\(\lfloor (5+2\sqrt{6})^n \rfloor = \lfloor 2a - t \rfloor = 2a - 1\)
利用矩阵乘法计算\(a\)即可
其实可以类似复数定义一种数为\(x+y\sqrt{6}\),直接算乘法。
#include<bits/stdc++.h>
using namespace std;
const int mod = 1024;
struct node{
long long a,b;
};
node operator * (node x,node y){
node c;
c.a = (x.a * y.a % mod + x.b * y.b % mod * 6 % mod ) % mod;
c.b = (x.a * y.b % mod + x.b * y.a % mod ) % mod;
return c;
}
node ksm(node x,int y){
node z; z.a = 1; z.b = 0;
while(y){
if(y & 1) z = z * x;
y >>= 1;
x = x * x;
}
return z;
}
int main(){
int T; scanf("%d",&T);
while(T --){
int n; scanf("%d",&n);
node x; x.a = 5; x.b = 2;
node y; y.a = 5; y.b = -2;
x = ksm(x,n); y = ksm(y,n);
long long ans = (x.a + y.a) % mod;
ans = (ans - 1 + mod) % mod;
printf("%lld\n",ans);
}
return 0;
}
标签:printf pid 题目 names namespace line ble show class
原文地址:https://www.cnblogs.com/zzhzzh123/p/13356701.html