zoukankan      html  css  js  c++  java
  • Codeforces757E.Bash Plays With Functions(积性函数 DP)

    题目链接

    (Description)

      q次询问,每次给定r,n,求(F_r(n))

    [ f_0(n)=sum_{u imes v=n}[(u,v)=1]\ f_{r+1}(n)=sum_{u imes v=n}frac{f_r(u)+f_r(v)}{2}]

    (Solution)

      首先将(f_r)的式子化为

    [f_{r+1}(n)=sum_{d|n}f_r(d) ]

      即(f_{r+1}(n))(f_r(n))(g(n)=1)的狄利克雷卷积。
      因为n的所有质因子之间对(f_0(n))的贡献是独立的,所以显然(f_0(n))为积性函数(为什么我还是不懂。。),那么(f_r(n))也为积性函数。
      于是可以对每个质因子单独计算,这样狄利克雷卷积就可以化成求和

    [f_{r+1}(p^k)=sum_{i=0}^kf_r(p^i) ]

      ((p^k)的所有因子即(p^i,i=0,1,ldots,k)
      同时可以发现(f_0(p^k)=[k eq 0]+1),即(f_0(p^k))的值与因子p无关,只与次数有关。
      那么DP,用(dp[i][j])表示(f_i(p^j)),则(dp[i][j]=sum_{k=0}^jdp[i-1][k])
      询问时对(n)分解质因数即可。

    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    const int N=1e6+3,M=21,mod=1e9+7,MAXIN=1<<18;
    
    int r,n,f[N+3][21],Primes[100000],cnt;
    char IN[MAXIN],*SS=IN,*TT=IN;
    bool Not_Prime[N+3];
    
    inline int read()
    {
    	int now=0,f=1;register char c=gc();
    	for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now*f;
    }
    #define Mod(a) (a>=mod)?a-=mod:0
    void Init()
    {
    //	Not_Prime[1]=1;
    	for(int i=2;i<N;++i)
    	{
    		if(!Not_Prime[i]) Primes[++cnt]=i;
    		for(int j=1;j<=cnt&&Primes[j]*i<N;++j)
    		{
    			Not_Prime[i*Primes[j]]=1;
    			if(!(i%Primes[j])) break;
    		}
    	}
    	f[0][0]=1;//f_r(p^0)=1
    	for(int i=1;i<M;++i) f[0][i]=2;
    	for(int sum=0,i=1;i<N;++i,sum=0)
    		for(int j=0;j<M;++j)
    		{
    			sum+=f[i-1][j], Mod(sum);
    			f[i][j]+=sum, Mod(f[i][j]);
    		}
    }
    int Solve(int r,int n)
    {
    	int ans=1,m=sqrt(n+0.5);
    	for(int i=1;i<=cnt&&Primes[i]<=m;++i)
    	{
    		if(n%Primes[i]) continue;
    		int t=0;
    		while(!(n%Primes[i])) n/=Primes[i],++t;
    		ans=1LL*ans*f[r][t]%mod;
    	}
    	if(n>1) ans=1LL*ans*f[r][1]%mod;//本身是个质数 
    	return ans;
    }
    
    int main()
    {
    //#ifndef	ONLINE_JUDGE
    //	freopen("757.in","r",stdin);
    //#endif
    
    	Init();
    	int t=read(),r,n;
    	while(t--)
    		r=read(),n=read(),printf("%d
    ",Solve(r,n));
    	return 0;
    }
    
    
  • 相关阅读:
    clickhouse-(04)-常用高阶函数
    clickhouse-(03)-库和表引擎
    clickhouse-(02)-适合的场景
    clickhouse-(01)-安装
    MySQL实战45讲-笔记
    Linux软连接和硬链接
    直接访问和间接访问
    指针和地址的区别
    配置Apache 运行CGI---------笔记
    配置Apache 运行CGI
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8324134.html
Copyright © 2011-2022 走看看