奇怪の公式:数论、素数筛、矩阵、欧拉定理
题意简述
给出 f(n,x,y)、gi、h(x) 的定义,求 h((gcd(gn,gx+y)mod105)!) 的值。
公式化简
公式 1
fn,x,y=(0≤i,2∣i∑nCni+i=0∑n(j=0∑nyjxn−jCnj)Cni)mod109+7
由引理
(x+y)n=i=0∑nyixn−iCni
带入 x=1,y=1 可得
0≤i∑nCni=i=0∑n1i1n−iCni=(1+1)n=2n
同理,带入 x=1,y=−1 可得
(1+(−1))n=i=0∑n(−1)i1n−iCni=0=i=0∑n(−1)iCni=Cn0−Cn1+Cn2−Cn3+⋯+(−1)nCnn→Cn0+Cn2+⋯=Cn1+Cn3+Cn5+⋯→0≤i,2∣i∑nCni=0≤i,2∣(i+1)∑nCni→20≤i,2∣i∑nCni=0≤i∑nCni=2n→0≤i,2∣i∑nCni=22n=2n−1
j=0∑nyjxn−jCnj=(x+y)n
i=0∑n(j=0∑nyjxn−jCnj)Cni=i=0∑n(x+y)nCni=(x+y)n2n
fn,x,y=(0≤i,2∣i∑nCni+i=0∑n(j=0∑nyjxn−jCnj)Cni)mod109+7=(2n−1+2n(x+y)n)mod109+7
可用快速幂解决。
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
gi={[i=1](fx,n,x+ygi−1+fy,x+y,ngi−2)mod109+7(i≤1)(i>1)
定义p=fx,n,x+y,q=fy,x+y,n
即:
gi={[i=1](pgi−1+qgi−2)mod109+7(i≤1)(i>1)
容易发现这是斐波那契数列,其初始矩阵为:
[pq10]
可用矩阵快速幂解决。
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
h(x)=d=1,x∣d∑xp1≤i∑∞i×(1−p)i−1(0<p<1)
p1≤i∑∞i×p(1−p)i−1(0<p<1)=p×p1≤i∑∞i×(1−p)i−1
定义
k=p1≤i∑∞i×(1−p)i−1=(1−p)0+2(1−p)1+⋅⋅⋅k−(1−p)k=1+2(1−p)+⋅⋅⋅−(1−p)−2(1−p)2−⋅⋅⋅=1+(1−p)+(1−p)2+⋅⋅⋅=0≤i∑∞(1−p)i=1−(1−p)1⋅(1−(1−p)n)(n→∞)=p1−(1−p)n(n→∞)
因为:
0<p<1→0<(1−p)<1
所以:
(1−p)n(n→∞)=an(0<a<1)(n→∞)→0
k−(1−p)k=k−(k−pk)=k−k+pk=pk=0≤i∑∞(1−p)i=p1→k=p21
即:
p1≤i∑∞i×p(1−p)i−1(0<p<1)=p×k=p×p21=p1
p×p1≤i∑∞i×(1−p)i−1=p×p1=1
h(x)=d=1,x∣d∑xp1≤i∑∞i×(1−p)i−1(0<p<1)=d=1,x∣d∑xk2(k=1)=τ(x)
由引理
τ(x)=p≤x∏(k=1∑∞(⌊pkx⌋)+1)(p∈Prime)
可得
h(x!)=p≤x!∏(k=1∑∞(⌊pkx!⌋)+1)(p∈Prime)
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);
}
计算结果
gcd(gn,gx+y)
由引理得:
gcd(gn,gx+y)=ggcd(n,x+y)
易得:
h((gcd(gn,gx+y)mod105)!)→h(x!)(x=gcd(gn,gx+y)mod105)
x 可 O(log2(max(n,x+y))) 得出,h(x!) 可用素数筛 O(x)(x<105)解决
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;
}
时间复杂度:O(Mod),其中 Mod≤105
预计得分:200pts
有帮助,赞一个