zoukankan      html  css  js  c++  java
  • 【题解】Loj6053 简单的函数

    Link

    ( ext{Solution:})

    显然的 Min_25 筛。因为题目已经告诉我们:函数是积性函数,并且素数及其次幂处的点值可以快速计算。

    先把给的函数拆成若干完全积性函数的和:我们观察到,当 (p) 为质数的时候, (f(p)=p-1.) 所以我们可以把函数拆成 (f(p)=p,f(p)=1) 这两个来分别计算出 (g_1(n,j),g_2(n,j)) 数组。

    但是对于 (2) 这个性质不成立怎么办?考虑计算答案的时候去掉影响就可以了,先按照 (1) 算即可。

    于是线性筛的时候我们需要维护一下素数的和,至于 (1) 这一部分自己算也行,为了板子化也可以求一下前缀和。

    同样地,记录下基本和组,并把所有数都当成质数来计算 (g,) 因为最后用到的只有素数的部分。

    考虑合并答案,实际上就是一样的式子:不断提出 (p[i]) 直到把因子提干净,一步步计算即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int mod=1e9+7;
    const int N=2e5+10;
    inline int Add(int x,int y) {
    	return (x+y)%mod;
    }
    inline int Mul(int x,int y) {
    	return 1ll*x*y%mod;
    }
    inline int dec(int x,int y) {
    	return (x-y+mod)%mod;
    }
    bool vis[N];
    int p[N],sum1[N],cnt,sq,sp,id1[N],id2[N],g1[N],n,g2[N],w[N],m,sum2[N];
    void pre() {
    	for(int i=2; i<=sq; ++i) {
    		if(!vis[i])p[++cnt]=i;
    		for(int j=1; j<=cnt&&i*p[j]<=sq; ++j) {
    			vis[i*p[j]]=1;
    			if(i%p[j]==0)break;
    		}
    	}
    	for(int i=1; i<=cnt; ++i) {
    		sum2[i]=Add(sum2[i-1],p[i]);
    		sum1[i]=sum1[i-1]+1,sum1[i]%=mod;
    	}
    }
    inline int f2(int x) {
    	x%=mod;
    	return x*(x+1)/2%mod;
    }
    inline int getid(int x) {
    	if(x<=sq)return id1[x];
    	return id2[n/x];
    }
    inline int S(int x,int j) {
    	if(p[j]>x)return 0;
    	int Ans=dec(dec(g2[getid(x)],g1[getid(x)]),dec(sum2[j],sum1[j]));
    	if(j==0&&x>=2)Ans=Add(Ans,2);
    	for(int i=j+1; i<=cnt&&p[i]*p[i]<=x; ++i) {
    		for(int e=1,sp=p[i]; sp<=x; sp*=p[i],++e) {
    			Ans=Add(Ans,Mul((p[i]^e)%mod,Add(S(x/sp,i),(e>1))));
    		}
    	}
    	return Ans;
    }
    signed main() {
    	scanf("%lld",&n);
    	sq=sqrt(n);
    	pre();
    	for(int l=1,r; l<=n; l=r+1) {
    		int d=n/l;
    		r=n/d;
    		w[++m]=d;
    		g1[m]=(w[m]-1+mod)%mod;
    		g2[m]=f2(w[m])-1;
    		g2[m]+=mod;g2[m]%=mod;
    		if(w[m]<=sq)id1[w[m]]=m;
    		else id2[r]=m;
    	}
    	for(int i=1; i<=cnt; ++i) {
    		for(int j=1; j<=m&&p[i]*p[i]<=w[j]; ++j) {
    			g1[j]=dec(g1[j],dec(g1[getid(w[j]/p[i])],sum1[i-1]));
    			g2[j]=dec(g2[j],Mul(p[i],dec(g2[getid(w[j]/p[i])],sum2[i-1])));
    		}
    	}
    	printf("%lld
    ",(S(n,0)+mod+1)%mod);
    	return 0;
    }
    
  • 相关阅读:
    idea git使用记录
    会计科目中的借贷理解
    git使用合集
    Unsupported major.minor version 52.0
    sts问题合集
    idea导入工程
    (转)解决mybatis的mapper.xml查询不出数据,结果一直为null问题
    战争热诚的python全栈开发之路
    Python机器学习笔记:SVM(4)——sklearn实现
    Python机器学习笔记:SVM(3)——证明SVM
  • 原文地址:https://www.cnblogs.com/h-lka/p/15081280.html
Copyright © 2011-2022 走看看