zoukankan      html  css  js  c++  java
  • BZOJ 4833: [Lydsy1704月赛]最小公倍佩尔数

    好诡异的一道题的说,不过我连那个(operatorname{lcm})(gcd)的互化都不知道,真是太屑了

    首先题目中给出的(f(n))是通项公式,我们可以用待定系数法解特征根方程然后求出递推式,求出来是

    [egin{cases}0&n=0\1&n=1\f(n)=2f(n-1)+f(n-2)&nge 2\end{cases} ]

    然后我们知道形如(f(n)=af(n-1)+bf(n-2))的递推方程都有性质(gcd(f(n),f(m))=f(gcd(n,m))),这个和斐波那契数列的证明类似,直接大力归纳即可

    然后接下来由于我们要求(g(n)=operatorname{lcm}_{i=1}^n f(i)),我们考虑经典的(operatorname{lcm})(gcd)的互化(以下(S={1,2,cdots,n})):

    [operatorname{lcm}(S)=prod_{Tsubseteq S,T ot=empty} gcd(T)^{(-1)^{|T|+1}} ]

    什么,你说这很新鲜,怎么推出来的?其实就是把min-max容斥放在了质数的指数上,然后指数的加法相当于乘法,于是就有了这个式子

    然后我们就有:

    [g(n)=prod_{Tsubseteq S,T ot=empty}f(gcd(T))^{(-1)^{|T|+1}} ]

    然后是不是很摸不着头脑,然后这道题最精髓的一步来了(绝妙!),由于题中保证了(f(n) ot =0),并且是在模意义下求答案,因此我们一定可以构造一个函数(h(n))满足(f(n)=prod_{d|n} h(d))

    然后代进去就有:

    [g(n)=prod_{Tsubseteq S,T ot=empty}f(gcd(T))^{(-1)^{|T|+1}}\=prod_{Tsubseteq S,T ot=empty}[prod_{d|gcd(T)} h(d)]^{(-1)^{|T|+1}}\=prod_{d=1}^n h(d)^{sum_{Tsubseteq S',T ot=empty} (-1)^{|T|+1}} ]

    其中(S'={1,2,cdots,lfloorfrac{n}{d} floor}),最后一步转化是提前(h(d))考虑它的贡献,注意关于(prod)的式子转化时本来的乘法到指数上就要变成加法

    看起来并没有让问题更简单是么,我们来看一下(h(d))的指数:

    [sum_{Tsubseteq S',T ot=empty} (-1)^{|T|+1}=sum_{i=1}^{lfloorfrac{n}{d} floor} (-1)^{i+1} C_{lfloorfrac{n}{d} floor}^i\=1+sum_{i=0}^{lfloorfrac{n}{d} floor} (-1)^iC_{lfloorfrac{n}{d} floor}^i=1 ]

    woc全体起立,思路清奇!这样就有(g(n)=prod_{i=1}^n h(i))

    然后考虑已知(f(n))的情况下怎么推出(h(n)),很简单,我们都知道莫比乌斯反演

    [f(n)=sum_{d|n} g(d)Leftrightarrow g(n)=sum_{d|n} mu(d) imes f(frac{n}{d}) ]

    然后把它的求和变成乘积即可(考虑反演公式的本质是关于质因数的容斥,而质数指数的加减就是原式子的乘除):

    [f(n)=prod_{d|n} g(d)Leftrightarrow g(n)=prod_{d|n} f(frac{n}{d})^{mu(d)} ]

    然后就做完了,说实话那一步转化真是太妙了,佩服出题人的脑洞

    #include<cstdio>
    #define RI register int
    #define CI const int&
    using namespace std;
    const int N=3e6+5;
    int t,n,mod,prime[N],cnt,mu[N],f[N],ivf[N],h[N],ans; bool vis[N];
    #define P(x) prime[j]
    inline void init(CI n)
    {
    	RI i,j; for (vis[1]=mu[1]=1,i=2;i<=n;++i)
    	{
    		if (!vis[i]) prime[++cnt]=i,mu[i]=-1;
    		int tp; for (j=1;j<=cnt&&(tp=i*P(j))<=n;++j)
    		{
    			vis[tp]=1; if (i%P(j)) mu[tp]=-mu[i]; else break;
    		}
    	}
    }
    #undef P
    inline int sum(CI x,CI y)
    {
    	int t=x+y; return t>=mod?t-mod:t;
    }
    inline int quick_pow(int x,int p=mod-2,int mul=1)
    {
    	for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
    }
    int main()
    {
    	for (scanf("%d",&t),init(3000000);t;--t)
    	{
    		RI i,j; for (scanf("%d%d",&n,&mod),f[1]=ivf[1]=1,i=2;i<=n;++i)
    		f[i]=sum(2*f[i-1]%mod,f[i-2]),ivf[i]=quick_pow(f[i]);
    		for (i=0;i<=n;++i) h[i]=1; for (i=1;i<=n;++i) for (j=i;j<=n;j+=i)
    		if (mu[j/i]==1) h[j]=1LL*h[j]*f[i]%mod; else
    		if (mu[j/i]==-1) h[j]=1LL*h[j]*ivf[i]%mod;
    		for (ans=0,i=1;i<=n;++i) h[i]=1LL*h[i]*h[i-1]%mod,ans=sum(ans,1LL*i*h[i]%mod);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    怎么看到数据库以前做过的日志?
    感觉很好的网站
    uview 滑动切换
    Flyweight享元(结构型模式)
    悟空,真的是空?
    Interpreter解释器(行为型模式)
    Proxy代理(结构型模式)
    [转]有一种爱叫索取
    Command命令(行为型模式)
    Composite组合(结构型模式)
  • 原文地址:https://www.cnblogs.com/cjjsb/p/12271334.html
Copyright © 2011-2022 走看看