• LOJ#6053. 简单的函数


    Description

    某一天,你发现了一个神奇的函数$f(x)$,它满足很多神奇的性质:

    $f(1)=1$。
    $f(p^c)=p⊕c$($p$ 为质数,$⊕$ 表示异或)。
    $f(ab)=f(a)f(b)$($a$ 与 $b$ 互质)。
    你看到这个函数之后十分高兴,于是就想要求出 $sum_{i=1}^n f(i)$。

    由于这个数比较大,你只需要输出 $sum_{i=1}^n f(i) mod(10^9+7)$。

    Solution

    发现对于除了$2$的所有质数,$p⊕1=p-1$,所以可以视为函数在质数处的取值等于$p-1$,最终答案+2

    所以$g(x)=x-1$,做Min_25筛,特判$n=1$的情况

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int tot,cnt,id1[100005],id2[100005];
    const int mod=1e9+7;
    long long w[200005],g1[200005],g0[200005],sp[100005],sq,prime[100005];
    bool vst[100005];
    long long n;
    inline long long read(){
        long long f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return f*w;
    }
    long long S(long long x,int y){
        if(prime[y]>=x)return 0;
        int id=x<=sq?id1[x]:id2[n/x];
        long long ret=(g1[id]-g0[id]+mod-(sp[y]-y+mod)+mod)%mod;
        for(int i=y+1;i<=tot&&prime[i]*prime[i]<=x;i++){
            long long temp=prime[i];
            for(int e=1;temp<=x;e++,temp*=prime[i])(ret+=(prime[i]^e)*(S(x/temp,i)+(e!=1))%mod)%=mod;
        }
        return ret;
    }
    int main(){
        n=read(),sq=sqrt(n);
        if(n==1)return puts("1"),0;
        for(int i=2;i<=sq;i++){
            if(!vst[i])prime[++tot]=i,sp[tot]=(sp[tot-1]+i)%mod;
            for(int j=1;j<=tot&&i*prime[j]<=sq;j++){
                vst[i*prime[j]]=true;
                if(!(i%prime[j]))break;
            }
        }
        for(long long i=1;i<=n;){
            long long j=n/(n/i);
            w[++cnt]=n/i%mod,g1[cnt]=((w[cnt]+1)*w[cnt]/2%mod+mod-1)%mod,g0[cnt]=(w[cnt]+mod-1)%mod,w[cnt]=n/i,n/i<=sq?id1[n/i]=cnt:id2[n/(n/i)]=cnt,i=j+1;
        }
        for(int i=1;i<=tot;i++)for(int j=1;j<=cnt&&prime[i]*prime[i]<=w[j];j++){
            int id=w[j]/prime[i]<=sq?id1[w[j]/prime[i]]:id2[n/(w[j]/prime[i])];
            (g1[j]+=mod-prime[i]*(g1[id]-sp[i-1])%mod)%=mod,(g0[j]+=mod-(g0[id]-i+1))%=mod;
        }
        printf("%lld
    ",S(n,0)+3);
        return 0;
    }
    简单的函数
  • 相关阅读:
    mysql之旅【第一篇】
    初探psutil
    Android的ListView分页功能
    Android中用PULL解析XML
    HTTPClient模块的HttpGet和HttpPost
    PB11.5创建及调用WebService
    Android平台使用SQLite数据库存储数据
    高通mm-camera平台 Camera bring up基本调试思路
    在Linux中使用crontab
    Linux 修改 hostname
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14457296.html
Copyright © 2020-2023  润新知