牛客多校第九场
题目链接
思路参考
这里说一个公式,算是化简了下
我们知道:
x
≡
a
m
o
d
  
(
p
1
)
,
x
≡
b
m
o
d
  
(
p
2
)
x≡a\mod(p1),x≡b\mod(p2)
x≡amod(p1),x≡bmod(p2)
其中p1,p2互质,我们可以直接套用中国剩余定理,但是有点麻烦
这个式子化简完后
x
x
x就为
(
a
+
(
b
−
a
)
∗
p
1
∗
p
1
−
1
)
%
(
p
1
∗
p
2
)
(a + (b - a)*p1*p1^{-1})\%(p1*p2)
(a+(b−a)∗p1∗p1−1)%(p1∗p2)
p
1
−
1
p1^{-1}
p1−1是p1再p2意义下的逆元。。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1e9;
const int loop1 = 768, p1 = 512;
const int loop2 = 7812500,p2 = 1953125;
const int inv = 1537323;
int quick(int a, int b, int p){
int ans = 1;
while(b){
if(b&1) ans = ans * a % p;
b >>= 1;
a = a*a%p;
}
return ans%p;
}
int solve(int n, int loop, int p, int m){
if(n == 1) return 1;
if(n == 2) return 2;
int y = n%loop;
int yu = 0;
if(y == 1) yu = 1;
if(y == 2) yu = 2;
int ans = 2,a = 1, b = 1;
for(int i = 3; i <= loop; i ++){
int c = (a + b)%p;
a = b;
b = c;
ans = (ans + quick(c , m , p))%p;
if(i == y) yu = ans;
}
return (ans*(n/loop)%p + yu)%p;
}
signed main()
{
int n,m;
scanf("%lld%lld",&n,&m);
int ans1 = solve(n, loop1, p1, m);
int ans2 = solve(n, loop2, p2, m);
//cout << quick(p1 , p2 - 2, p2) << " " << quick(p2, p1 - 2, p1) << endl;
int ans = (ans1%(p1*p2) + (ans2 - ans1)*p1%(p1*p2)*inv%(p1*p2))%(p1*p2);
printf("%lld\n",ans);
}