Comet OJ Contest #13 D

Comet OJ Contest #13 D

$\displaystyle \sum_{i=0}^{\left\lfloor\frac{n}{2}\right\rfloor} a^{i} b^{n-2 i}\left(\begin{array}{c}{n} \\ {2 i}\end{array}\right)$

$T \leq 10^4 , n , m , p \leq 10^{18}$

注意,由于$p$不一定是质数,而且数据范围看起来很快速幂所有貌似只能快速幂。

这个式子可以化成:

$\displaystyle \sum_{i=0}^{\left\lfloor\frac{n}{2}\right\rfloor} {\sqrt a}^{2i} b^{n-2 i}\left(\begin{array}{c}{n} \\ {2 i}\end{array}\right)$

然后其实就是$(\sqrt a + b)^n$的偶数次项的和。

偶数次项其实可以化成$\frac{1}{2} ( (\sqrt a + b)^n - (\sqrt a - b) ^ n )$ 当然这是当$n$为偶数时,如果是奇数要反过来。

这个式子可以直接类似复数的快速幂,因为我们知道最后一定不会剩下根号。

当然,也可以看成一个特征方程的根,就是一个$f(1) = 1 , f(2) = b , f(n) = 2bf(n - 1) + (-b^2+a) f(n - 2)$。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*Heroes Never Die!*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define int __int128_t
#define ll __int128_t
#define N 2
struct mtrx{
ll a[3][3];
} tmp , cur , ans ;
ll a , b , P;
void mul( mtrx& a , mtrx& b ) {
memset(tmp.a,0,sizeof tmp.a);
for( ll i = 0 ; i < N ; ++ i )
for( ll p = 0 ; p < N ; ++ p )
if(a.a[i][p])
for( ll j = 0 ; j < N ; ++ j )
tmp.a[i][j] += a.a[i][p] * b.a[p][j] , tmp.a[i][j] %= P;

}

void power( ll n ) {
memset(cur.a , 0 , sizeof cur.a) , memset(ans.a,0,sizeof ans.a);
cur.a[0][0] = 2 * b % P , cur.a[0][1] = ( - b * b % P + a + P ) % P;
cur.a[1][0] = 1;
ans.a[0][0] = 1, ans.a[1][1] = 1;
while( n ) {
if( n & 1 ) mul( ans , cur ) , ans = tmp;
mul( cur , cur ) , cur = tmp , n >>= 1 ;
}
}
ll n;
inline __int128_t read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
inline void print(__int128_t x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) print(x/10);
putchar(x%10+'0');
}
signed main() {
//freopen("input","r",stdin);
signed T; cin >> T;
while( T-- ){
n = read() , a = read() , b = read( ) , P = read();
power(n - 1);
print((ans.a[0][0] * b % P + ans.a[0][1]) % P); puts("");
}
}
//qwq
文章作者: yijan
文章链接: https://yijan.co/old59/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yijan's Blog