官方题解 | 奇怪の公式
2025-03-01 20:08:27
发布于:云南
187阅读
0回复
0点赞
奇怪の公式:数论、素数筛、矩阵、欧拉定理
题意简述
给出 、、 的定义,求 的值。
公式化简
公式 1
由引理
带入 可得
同理,带入 可得
可用快速幂解决。
long long pw(long long a,long long b,long long mod) {
long long ans=1;
a%=mod;
while (b){
if (b&1){
ans=ans*a%mod;
}
a=a*a%mod;
b>>=1;
}
return ans;
}
long long f(long long n, long long x, long long y){
return ((pw(x+y,n,MOD)*pw(2,n,MOD))%MOD+pw(2,n-1,MOD))%MOD;
}
公式 2
定义
即:
容易发现这是斐波那契数列,其初始矩阵为:
可用矩阵快速幂解决。
struct Mat{
long long mat[2][2];
Mat(){
mat[0][0]=mat[1][1]=1;
mat[0][1]=mat[1][0]=0;
}
Mat operator*(const Mat& ot) const{
Mat res;
res.mat[0][0]=(mat[0][0]*ot.mat[0][0]+mat[0][1]*ot.mat[1][0])%MOD;
res.mat[0][1]=(mat[0][0]*ot.mat[0][1]+mat[0][1]*ot.mat[1][1])%MOD;
res.mat[1][0]=(mat[1][0]*ot.mat[0][0]+mat[1][1]*ot.mat[1][0])%MOD;
res.mat[1][1]=(mat[1][0]*ot.mat[0][1]+mat[1][1]*ot.mat[1][1])%MOD;
return res;
}
};
Mat mat_pw(Mat a,long long b){
Mat res;
while (b) {
if (b&1){
res=res*a;
}
a=a*a;
b>>=1;
}
return res;
}
long long fib(long long n){
if (n==0){
return 0;
}
Mat base;
base.mat[0][0]=f(x,n,x+y);
base.mat[0][1]=f(y,x+y,n);
base.mat[1][0]=1;
base.mat[1][1]=0;
Mat res=mat_pw(base,n-1);
return res.mat[0][0];
}
公式 3
定义
因为:
所以:
即:
由引理
可得
long long g(long long i,long long x,long long y) {
if (i<=1){
long long fi=f(i,x,y);
long long fx=f(x,i,y-1);
long long pff=pw(fi,fx,MOD);
return pff;
}
return fib(i);
}
计算结果
由引理得:
易得:
可 得出, 可用素数筛 解决
vector<int> p;
bool vis[1000010];
void init(){
memset(vis,1,sizeof vis);
vis[0]=vis[1]=0;
for (int i=2;i<1000010;i++) {
if (vis[i]){
p.push_back(i);
for (int j=2*i;j<1000010;j+=i) {
vis[j]=0;
}
}
}
}
正解
#include <bits/stdc++.h>
using namespace std;
const int MOD=1e9+7;
long long n,x,y;
long long pw(long long a,long long b,long long mod) {
long long ans=1;
a%=mod;
while (b){
if (b&1){
ans=ans*a%mod;
}
a=a*a%mod;
b>>=1;
}
return ans;
}
long long f(long long n, long long x, long long y){
return ((pw(x+y,n,MOD)*pw(2,n,MOD))%MOD+pw(2,n-1,MOD))%MOD;
}
struct Mat{
long long mat[2][2];
Mat(){
mat[0][0]=mat[1][1]=1;
mat[0][1]=mat[1][0]=0;
}
Mat operator*(const Mat& ot) const{
Mat res;
res.mat[0][0]=(mat[0][0]*ot.mat[0][0]+mat[0][1]*ot.mat[1][0])%MOD;
res.mat[0][1]=(mat[0][0]*ot.mat[0][1]+mat[0][1]*ot.mat[1][1])%MOD;
res.mat[1][0]=(mat[1][0]*ot.mat[0][0]+mat[1][1]*ot.mat[1][0])%MOD;
res.mat[1][1]=(mat[1][0]*ot.mat[0][1]+mat[1][1]*ot.mat[1][1])%MOD;
return res;
}
};
Mat mat_pw(Mat a,long long b){
Mat res;
while (b) {
if (b&1){
res=res*a;
}
a=a*a;
b>>=1;
}
return res;
}
long long fib(long long n){
if (n==0){
return 0;
}
Mat base;
base.mat[0][0]=f(x,n,x+y);
base.mat[0][1]=f(y,x+y,n);
base.mat[1][0]=1;
base.mat[1][1]=0;
Mat res=mat_pw(base,n-1);
return res.mat[0][0];
}
long long g(long long i,long long x,long long y) {
if (i<=1){
long long fi=f(i,x,y);
long long fx=f(x,i,y-1);
long long pff=pw(fi,fx,MOD);
return pff;
}
return fib(i);
}
vector<int> p;
bool vis[1000010];
void init(){
memset(vis,1,sizeof vis);
vis[0]=vis[1]=0;
for (int i=2;i<1000010;i++) {
if (vis[i]){
p.push_back(i);
for (int j=2*i;j<1000010;j+=i) {
vis[j]=0;
}
}
}
}
long long cd(long long x){
long long ans=1;
for (int ps:p){
long long et=0;
long long pr=ps;
while (pr<=x){
et+=x/pr;
if (pr>x/ps){
break;
}
pr*=ps;
}
ans=(ans*(et+1))%MOD;
}
return ans;
}
int main() {
init();
cin>>n>>x>>y;
long long gnxy=__gcd(n,x+y);
long long gg=g(gnxy,x,y);
long long gm=gg%(100000);
long long phi=cd(gm);
cout<<phi<<endl;
return 0;
}
时间复杂度:,其中
预计得分:
全部评论 5
牛
2025-11-22 来自 广东
1


红鹿邓1周前 来自 浙江
0







1周前 来自 浙江
0!
2025-11-23 来自 浙江
0qp

2025-07-24 来自 浙江
0





















有帮助,赞一个