zoukankan      html  css  js  c++  java
  • 简单的函数——Min_25筛

    %%yyb

    %%zsy

    就是实现一下Min-25筛 筛积性函数的操作

    首先要得到

    $G(M,j)=sum_{t=j}^{cnt} sum_{e=1}^{p_t^{e+1}<=M} [phi(p_t^e)*G([M/(p_t^e)],t+1)+phi(p_t^{(e+1)})]$
    ​ $+(F(M)-(F(p_{j-1})))$

    先要预处理后面的部分,得到$F(M)$和$F(p_{j-1})$

    $F(p_{j-1})$可以直接筛素数的时候前缀和计算一下

    $F(M)$就要利用第一步的筛法了

    发现,除了2之外的质数都是奇数,所以f(p^1)=p xor 1=p-1

    对于2要特判

    对于G,直接根据式子大力计算即可。

    递归处理。由于值还是比较分散的,所以没有记忆化的必要。(而且状态很多,对空间极为不友好)

    剪枝:pri[t]的平方大于n就不用继续算了。

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define reg register int
    #define int long long
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    const int N=5e5+2;
    const int M=5e5+2;
    const int mod=1e9+7;
    int pri[M],tot;
    int sum[M];//pre of prime
    bool vis[N];
    int sqr;
    ll f[N],g[N],h[N];
    void sieve(int n){
        for(reg i=2;i<=n;++i){
            if(!vis[i]){
                vis[i]=1;
                pri[++tot]=i;
            }
            for(reg j=1;j<=tot;++j){
                if(i*pri[j]>n) break;
                vis[i*pri[j]]=1;
                if(i%pri[j]==0) break;
            }
        }
        for(reg i=1;i<=tot;++i){
            sum[i]=(sum[i-1]+pri[i])%mod;
            g[i]=(g[i-1]+(pri[i]^1))%mod;
        }
    }
    int id1[N],id2[N];
    
    ll val[N];
    ll n;
    int S(int x,int j){
        if(x<=1||x<pri[j]) return 0;
        cout<<" xx "<<x<<" jj "<<j<<endl;
        int d=(x<=sqr)?id1[x]:id2[n/x];
        int ret=(f[d]-g[j-1]+mod)%mod;
        for(reg t=j;t<=tot&&pri[t]*pri[t]<=x;++t){
            int now=pri[t];
            for(reg e=1;now*pri[t]<=x;now=now*pri[t],++e){
                ret=(ret+(pri[t]^e)*S(x/now,t+1)%mod+(pri[t]^(e+1))%mod)%mod;
            }
        }
        return ret;
    }
    int main(){
        scanf("%lld",&n);
        if(n==1){
            puts("1");return 0;
        }
        sqr=sqrt(n);
    //    cout<<" sqr "<<sqr<<endl;
        sieve(sqr);
    //    cout<<" after sieve "<<endl;
        int m=0;
        for(ll i=1,x;i<=n;i=x+1){
            x=n/(n/i);
            val[++m]=n/i;
            if(val[m]<=sqr) id1[val[m]]=m;
            else id2[n/val[m]]=m;
        }
        for(reg i=1;i<=m;++i){
            f[i]=val[i]-1;h[i]=(((ll)val[i]%mod*(val[i]%mod+1))/2-1+mod)%mod;
        }
        for(reg j=1;j<=tot;++j){
            for(reg i=1;i<=m&&(ll)pri[j]*pri[j]<=val[i];++i){
                int to=(val[i]/pri[j])<=sqr?id1[val[i]/pri[j]]:id2[n/(val[i]/pri[j])];
                f[i]=(f[i]-(f[to]-(j-1))+mod+mod)%mod;
                h[i]=(h[i]-pri[j]*(h[to]-sum[j-1]+mod)%mod+mod)%mod;
            }
        }
        for(reg i=1;i<=m;++i){
            if(val[i]>=2) f[i]=(h[i]-f[i]+2+mod)%mod;
            else f[i]=0;
        }
        //cout<<" after prewrk "<<endl;
        printf("%lld",(S(n,1)+1)%mod);
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/1/13 17:03:03
    */
  • 相关阅读:
    FRAM在智能电子式电表中的应用
    element UI实现动态生成多级表头
    小微信小程序开发相关网站
    响应式开发bootstrap
    媒体查询
    前端导出功能实现的两种方式
    watch监听对象遇坑
    vue中使用v-for时为什么要用到key?为什么不能用index作为key?
    vue中我改变了data中的一个值,但现在视图上没有实时更新,请问我怎么拿到更新后的值?
    python 链接数据库的模块
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10263570.html
Copyright © 2011-2022 走看看