zoukankan      html  css  js  c++  java
  • 题解 P4994 【终于结束的起点】

    这道题,发现暴力能过时,喷了3k的血。。。本人花了近半小时打表找规律。。。然后真找出来一些了。。。

    1.f[x^n]=f[x]*(x^(n-1))

    2.设x,y为不相同的质数,则f[x^a*y^b]=lcm(f[x^a],f[y^b])。

    3.对于一个质数x,他的f[x]极小(似乎都很小??)

    对于一个n,我们就可以将他进行质因数分解:设n=x^ay^b...

    然后我们暴力求出f[x],f[y],套上规律一,求出f[x^a],f[y^b],再套规律二,就可以求出来了。。。

    分析:因为n<=706150,所以我们最多只需要暴力7个素数,而经试验,每个素数的f最多只有自身的2倍多(除了5是4倍。。。) 所以暴力运行次数最多为14*n(稳过。。。)

    对于求f[x^a]套个log的快速幂,lcm也是log...所以,所有数据都是稳过的。。。

    奉上代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=10000000;
    int M;
    bool is_not_prime[N];
    int f[N],zhi[N],e;
    inline void sai(int maxe){
        for(int i=2;i<=maxe;++i){
            if(!is_not_prime[i]){
                zhi[++e]=i;
                for(int j=i;j<=maxe/i;++j){
                    is_not_prime[i*j]=1;
                }
            }
        }
    }
    inline int gcd(int x,int y){
        return x%y==0?y:gcd(y,x%y);
    }
    inline int lcm(int x,int y){//lcm
        return x/gcd(x,y)*y;
    }
    inline int bl(int x){//暴力计算
        f[1]=1;
        for(int i=2;i;++i){
            f[i]=f[i-1]+f[i-2];
            f[i]%=x;
            if(f[i]==1&&f[i-1]==0){
                return i-1;
            }
        }
    }
    inline int ksm(int x,int y){
        int ans=1;
        while(y){
            if(y&1){
                ans*=x;
            }
            x*=x;
            y>>=1;
        }
        return ans;
    }
    inline int div(int x){
        int ans=1;
        for(int i=1;i<=e;++i){
            if(zhi[i]>x){
                break;
            }
            if(x%zhi[i]==0){//分解质因数
                int tim=0;
                while(x%zhi[i]==0){//求幂
                    tim++;
                    x/=zhi[i];
                }
                int ti=bl(zhi[i]);
                ti*=ksm(zhi[i],tim-1);
                ans=lcm(ans,ti);
            }
        }
        return ans;
    } 
    int main(){
        //2^n=3*2^(n-1)
        //3^n=8*3^(n-1)
        //5^n=20*5^(n-1)
        sai(706150);//筛法筛质数
        int x;
        scanf("%d",&x);
        printf("%d
    ",div(x));
        return 0;
    }
  • 相关阅读:
    允许电脑被远程连接
    电脑更改用户密码
    HTML ------- 对文本进行操作的元素
    货币的发展
    SQL-----数据库三种删除方式详解
    HTML -------- 标签、元素、属性,
    HTML -------- 简介
    SQL --------------- HAVING 子句
    SQL --------------- GROUP BY 函数
    Shell编程——运算符
  • 原文地址:https://www.cnblogs.com/ThinkofBlank/p/10146179.html
Copyright © 2011-2022 走看看