【2019牛客暑期多校训练营(第五场)B题】generator 1(广义斐波那契数列循环节+积性函数)

思路:

形如f(n)=af(n-1)+bf(n-2)的数列就叫做广义斐波那契数列。

设g(x)为mo=x时的f(n)的循环节,即f(n)\equivf(n%g(x))   (mod x),

则g(x)是一个积性函数。

g(x)=\left\{\begin{matrix} (x+1)*(x-1) & x \in \mathbb{P}\\ g(\frac{x}{p_i})*p_i & x\notin \mathbb{P} , p_i^2|x\\ g(\frac{x}{p_i})*g(p_i) & x\notin \mathbb{P} ,p_i|x,gcd(pi,\frac{x}{p_i})=1 \end{matrix}\right.

=\prod g(p_i) * \frac{x}{\prod p_i}

=phi(x)*\prod (p_i+1)

x为质数时的证明

ps:x不是质数时的结论是下午做题时的猜想,不保证正确性。可以过这个题,但是万一是水过的呢,之后还会再跑程序验证下。

代码:

#include
#include
typedef long long ll;
const int N=1000000+10;
struct Node{
    int r,c;
    ll jz[3][3];
    Node(){
        memset(jz,0,sizeof(jz));
    }
};
ll x0,x1,a,b,n,md,mmd;
char s[N];
int pn,pri[100000+10];
void init(){
    ll lim;
    for(int i=2;i<=100000;i++){
        if(!pri[i]) pri[pn++]=i;
        for(int j=0;j100000) break;
            pri[lim]=1;
            if(i%pri[j]==0) break; 
        }
    }
}
ll solve(ll x){
    ll ans1=1,ans2=1,xx=x;
    for(int i=0;ix) break;
        if(x%pri[i]==0){
            ans1*=(pri[i]-1)*(pri[i]+1);
            ans2*=pri[i];
            while(x%pri[i]==0) x/=pri[i];
        }
    }
    if(x>1){
        ans1*=(x-1)*(x+1);
        ans2*=x;
    }
    return xx/ans2*ans1;
}
ll mul(ll x,ll y,ll z){
    x%=z;
    y%=z;
    ll ans=0;
    while(y){
        if(y&1){
            ans+=x;
            if(ans>=z) ans-=z;
        }
        x<<=1;
        if(x>=z) x-=z;
        y>>=1;
    }
    return ans;
}
Node Nmul(Node x,Node y,ll z){
    Node ans;
    ans.r=x.r;
    ans.c=y.c;
    for(int i=0;i=z) ans.jz[i][j]%=z;
            }
    return ans;
}
Node Npow(Node x,ll y,ll z){
    Node ans;
    ans.r=x.r;
    ans.c=x.c;
    for(int i=0;i>=1;
    }
    return ans;
}
int main(){
    init();
    while(~scanf("%lld%lld%lld%lld",&x0,&x1,&a,&b)){
        scanf("%s%lld",s,&md);
        mmd=solve(md);
        n=0;
        int lens=strlen(s);
        for(int i=0;i=mmd) n-=mmd;
        }
        Node A,T;
        A.r=2;
        A.c=1;
        A.jz[0][0]=x1;
        A.jz[1][0]=x0;
        T.r=2;
        T.c=2;
        T.jz[0][0]=a;
        T.jz[0][1]=b;
        T.jz[1][0]=1;
        if(n>1){
            T=Npow(T,n-1,md);
            A=Nmul(T,A,md);
        }
        printf("%lld\n",A.jz[0][0]);
    }
    return 0;
}

 

你可能感兴趣的:(◈数论)