• [bzoj4916] 神犇和蒟蒻


    Description

    很久很久以前,有一只神犇叫yzy;

    很久很久之后,有一只蒟蒻叫lty;

    Input

    请你读入一个整数N;1<=N<=1E9,A、B模1E9+7;

    Output

    请你输出一个整数(A=sum_{i=1}^N{mu (i^2)})

    请你输出一个整数(B=sum_{i=1}^N{varphi (i^2)})

    Sample Input

    1
    

    Sample Output

    1
    1
    

    solution

    杜教筛基础题.

    对于第一问,由于当(igeqslant 2)的时候(mu(i^2)=0),所以直接puts("1")就好了.

    [f(n)=varphi(n^2)=varphi(n)*n\ S(n)=sum_{i=1}^{n}f(i) ]

    然后把杜教筛的套路式子搬出来:

    [S(n)=sum_{i=1}^{n}(f*g)(i)-sum_{i=2}^{n}g(i)S(lfloorfrac{n}{i} floor) ]

    然后考虑凑出这个(g)

    [(f*g)(n)=sum_{i|n}i*varphi(i)*g(frac{n}{i}) ]

    看到这个系数(i)很不爽,考虑把他消掉,令(g(n)=n),得:

    [(f*g)(n)=sum_{i|n}i*varphi(i)*frac{n}{i}=n*sum_{i|n}varphi(i)=n^2 ]

    然后发现这个东西的前缀和很好求,就直接带到套路式里得:

    [S(n)=frac{n(n+1)(2n+1)}{6}-sum_{i=2}^niS(lfloorfrac{n}{i} floor) ]

    然后记忆化一下,递归求这个,线筛出前(1e7)就做完了.

    #include<bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    
    void read(int &x) {
    	x=0;int f=1;char ch=getchar();
    	for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    	for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
    
    void print(int x) {
    	if(x<0) x=-x,putchar('-');
    	if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    const int maxn = 1e7+1;
    const int mod = 1e9+7;
    
    int phi[maxn],pri[maxn],vis[maxn],n,tot,inv2,inv6;
    
    void sieve() {
    	phi[1]=1;
    	for(int i=2;i<maxn;i++) {
    		if(!vis[i]) pri[++tot]=i,phi[i]=i-1;
    		for(int t,j=1;j<=tot&&i*pri[j]<maxn;j++) {
    			vis[t=i*pri[j]]=1;
    			if(!(i%pri[j])) {phi[t]=phi[i]*pri[j];break;}
    			phi[t]=phi[i]*phi[pri[j]];
    		}
    	}
    	for(int i=1;i<maxn;i++) phi[i]=(phi[i-1]+phi[i]*i)%mod;
    }
    
    map<int,int > Phi;
    
    int qpow(int a,int x) {
    	int res=1;
    	for(;x;x>>=1,a=a*a%mod) if(x&1) res=res*a%mod;
    	return res;
    }
    
    int calc(int n) {return n%mod*(n%mod+1)%mod*inv2%mod;}
    
    int sum(int n) {
    	if(n<maxn) return phi[n];
    	if(Phi[n]) return Phi[n];
    	int res=n*(n+1)%mod*(n+n+1)%mod*inv6%mod;
    	int T=2;//printf("%lld
    ",Phi[n]);
    	while(T<=n) {
    		int pre=T;T=n/(n/T);
    		res=(res-sum(n/T)*(calc(T)-calc(pre-1))%mod)%mod;T++;
    	}
    	return Phi[n]=(res%mod+mod)%mod;
    }
    
    signed main() {
    	sieve();inv2=qpow(2,mod-2);inv6=qpow(6,mod-2);
    	int n;read(n);write(1ll),write(sum(n));
    	return 0;
    }
    
    
  • 相关阅读:
    微信公众平台接口测试账号申请
    Windows平台下tomcat+java的web程序持续占cpu问题调试
    mysql存储过程基础
    Mysql权限控制
    MySQL开启federated引擎实现数据库表映射
    JAVA中Set集合--HashSet的使用
    在js中嵌套java代码
    MySql计算两个日期的时间差函数
    关于easyui combobox下拉框实现多选框的实现
    利用excel办公软件快速拼凑sql语句
  • 原文地址:https://www.cnblogs.com/hbyer/p/10071615.html
Copyright © 2020-2023  润新知