zoukankan      html  css  js  c++  java
  • Min_25筛

    min_25筛

    (ans=sum_{i=1}^nf(i),nin[1,1e10])

    满足:

    1. (f(p))是关于p的多项式
    2. (f(p^c))快速求得(通常是(O(1))
    3. (f(n))为积性函数

    时间复杂度(O(frac{n^{frac34}}{logn}))

    预处理

    [g(n,j)=sum_{i=1}^n[iin P||minp(i)>p_j]f`(i) ]

    初始值(g(n,0))是把所有数当成质数的函数和(此时的(f`(i))已被拆成完全积性函数)

    [g(n,|P|)=sum_{i=1}^n[iin P]f`(i) ]

    考虑埃氏筛的过程,每次把最小质因子为(p_j)的筛去

    转移

    [g(n,j)=g(n,j-1),p_j^2>n ]

    [g(n,j)=g(n,j-1)-f`(p_j)(g(lfloorfrac n {p_j} floor,j-1)-sum_{i=1}^{j-1}[iin P]f`(i)),p_j^2<=n ]

    但这样是(O(n|P|))的,考虑优化,发现n的取值只有(sqrt n)种,于是“手动”离散化,第二维可滚动掉,时间(O(sqrt n|P|)),空间(O(sqrt n))

    计算答案

    [s(n,j)=sum_{i=1}^n[minp(i)ge P_j]f(i) ]

    [ans=s(n,1) ]

    转移:(分质数和合数,合数部分枚举最小质因子及其次数)

    [s(n,j)=g(n,|P|)-sum_{i=1}^{j-1}f(p_i)+sum_{p_kleq sqrt x,kge j}sum_{e>0,p_k^eleq n}f(p_k^e)(s(lfloorfrac n{p_k^e} floor,k+1)+[e>1]) ]

    采用递归方式计算

    注意:1不是质数也不是合数,最后要加上

    例:LOJ6053简单的函数

    (ans=sum_{i=1}^nf(i)\%1000000007,nin[1,1e10])

    性质:

    1. (f(1)=1)
    2. (f(p^c)=poplus c)
    3. (f(ab)=f(a)f(b),gcd(a,b)=1)

    SOL:

    除2外的质数(f(p)=p-1)拆成(f_1(p)=p,f_2(p)=1)

    对应求出(g(n,j),h(n,j))

    初值

    [s(n,j)=g(n,|P|)-h(n,|P|)-sum_{i=1}^{j-1}f(p) ]

    注意:2要特判一下

    CODE:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return f==1?x:-x;
    }
    const int N=250004,mod=1e9+7,inv2=5e8+4;
    int n,sq,tot,m,h[N],g[N],sp[N],b[N],pri[N],id1[N],id2[N],w[N];
    inline void pre(int mx){
    	for(int i=2;i<=mx;i++){
    		if(!b[i]){pri[++tot]=i;sp[tot]=sp[tot-1]+i;}
    		for(int j=1;j<=tot&&pri[j]*i<=mx;j++){
    			b[pri[j]*i]=1;
    			if(i%pri[j]==0)break;
    		}
    	}
    }
    int S(int x,int y){
    	if(x<=1||pri[y]>x)return 0;
    	int k=(x<=sq)?id1[x]:id2[n/x],ret=(g[k]-h[k]-sp[y-1]+y-1)%mod;
    	if(y==1)ret+=2;
    	for(int i=y,t1,t2;i<=tot&&pri[i]*pri[i]<=x;i++){
    		t1=pri[i];t2=pri[i]*pri[i];
    		for(int j=1;t2<=x;j++,t1=t2,t2*=pri[i])
    			(ret+=S(x/t1,i+1)*(pri[i]^j)%mod+(pri[i]^(j+1)))%=mod;
    	}
    	return ret;
    }
    signed main(){
    	n=read();sq=sqrt(n);
    	pre(sq);
    	for(int i=1,j;i<=n;i=j+1){
    		j=n/(n/i);
    		w[++m]=n/i;//手动离散化
    		g[m]=(w[m]%mod)*(w[m]%mod+1)%mod*inv2%mod-1;//f1(x)=x
    		h[m]=(w[m]-1)%mod;//f2(x)=1 拆成积性函数
    		if(w[m]<=sq)id1[w[m]]=m;
    		else id2[j]=m; 
    	}
    	for(int j=1,k;j<=tot;j++)
    		for(int i=1;i<=m&&pri[j]*pri[j]<=w[i];i++){
    			k=(w[i]/pri[j]<=sq)?id1[w[i]/pri[j]]:id2[n/(w[i]/pri[j])];
    			(g[i]-=pri[j]*(g[k]-sp[j-1]))%=mod;
    			(h[i]-=h[k]-j+1)%=mod;
    		} 
    	cout<<(S(n,1)+1+mod)%mod;
    	return (0-0);
    }
    
  • 相关阅读:
    Sokect简单入门(1)TCP协议一
    Tomcat内存溢出 解决方法
    服务器配置 ssl 证书,Nginx配置
    优秀的博客文章记录
    SpringBoot实现优雅的关机
    关于 redis 的 数据类型 和 内存模型
    微信, qq 支付宝 等相关开发 资源 记录
    设计模式 之 单列设计模式
    Swagger
    MQ服务器奔溃解决过程
  • 原文地址:https://www.cnblogs.com/aurora2004/p/12636109.html
Copyright © 2011-2022 走看看