zoukankan      html  css  js  c++  java
  • bzoj4173 数学

    bzoj4173 数学
    欧拉(varphi)函数,变形还是很巧妙的

    求:

    [varphi(n)cdotvarphi(m)cdotsum_{nmod k+mmod kge k}varphi(k)mod 998244353,n,mle 10^{15} ]


    首先,对(sum)下面那一坨进行变形
    很容易知道,(nmod k+mmod k=n-lfloordfrac{n}{k} floorcdot k+m-lfloordfrac{m}{k} floorcdot k<2k)
    那么对不等式同时除以(k),就是(1le dfrac{n+m}{k}-lfloordfrac{n}{k} floor-lfloordfrac{m}{k} floor<2)
    然后把那个(frac{n+m}{k})来个下取整,这个式子就变成了(1),也就是:

    [lfloorfrac{n+m}{k} floor-lfloorfrac{n}{k} floor-lfloorfrac{m}{k} floor=1 ]

    所以只看那个(sum)就是:

    [sum_{lfloorfrac{n+m}{k} floor-lfloorfrac{n}{k} floor-lfloorfrac{m}{k} floor=1}varphi(k) ]

    然后又由于(lfloordfrac{n+m}{k} floor-lfloordfrac{n}{k} floor-lfloordfrac{m}{k} floor=1)只有(0,1)两个值,是(1)符合要求是(0)不符合,所以可以把上式继续拆:

    [sum_{k=1}^{n+m}varphi(k)cdot(lfloorfrac{n+m}{k} floor-lfloorfrac{n}{k} floor-lfloorfrac{m}{k} floor) ]

    [sum_{k=1}^{n+m}varphi(k)lfloorfrac{n+m}{k} floor-sum_{k=1}^nvarphi(k)lfloorfrac{n}{k} floor-sum_{k=1}^mvarphi(k)lfloorfrac{m}{k} floor ]


    下面考虑如何求(sum_{i=1}^nvarphi(i)lfloordfrac{n}{i} floor)就行了

    想要推这个,先证明一个结论:(n=sum_{dmid n}varphi(d))
    列举出如下分数:
    (dfrac{1}{n},dfrac{2}{n},cdots,dfrac{n}{n})
    然后把他们化简
    当且仅当(dmid n,gcd(a,d)=1),分数(frac{a}{d})出现在其中
    那么,以(d)为分母的分数有(varphi(d))个,(d)可以取遍(n)的所有因数
    又因为这些分数的个数是(n),所以(n=sum_{dmid n}varphi(d))

    那么把(sum)里面那一些,理解为(lfloorfrac{n}{i} floor)(varphi(i))相加
    而从(1)(n)中,有(lfloorfrac{n}{i} floor)个数是(i)的倍数,所以我们枚举这(n)个数:

    [sum_{i=1}^nvarphi(i)lfloordfrac{n}{i} floor=sum_{j=1}^nsum_{imid j}varphi(i) ]

    然后用刚才说的结论,变形为:

    [sum_{j=1}^n j ]

    所以答案就清晰了:

    [varphi(n)cdotvarphi(m)cdotsum_{nmod k+mmod kge k}varphi(k)=varphi(n)cdotvarphi(m)cdot(sum_{i=1}^{n+m}i-sum_{i=1}^n i-sum_{i=1}^m i)=varphi(n)cdotvarphi(m)cdot ncdot m ]


    最后由于数很大一定要频繁取模

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<iomanip>
    #include<cstring>
    #define reg register
    #define EN std::puts("")
    #define LL long long
    inline LL read(){
    	register LL x=0;register int y=1;
    	register char c=std::getchar();
    	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
    	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
    	return y?x:-x;
    }
    #define mod 998244353
    inline LL phi(LL x){
    	reg LL ret=x;
    	int sqrt=std::ceil(std::sqrt(x));
    	for(reg int i=2;i<=sqrt;i++){
    		if(!(x%i)) ret=ret/i*(i-1);
    		while(!(x%i)) x/=i;
    	}
    	if(x>1) ret=ret/x*(x-1);
    	return ret;
    }
    int main(){
    	LL n=read(),m=read();
    	std::printf("%lld",phi(n)%mod*(phi(m)%mod)%mod*(n%mod)%mod*(m%mod)%mod);
    	return 0;
    }
    
  • 相关阅读:
    <<程序员>> 杂志网站
    插入排序
    冒泡排序
    TCP/IP编程实现远程文件传输
    选择排序
    防止基础表数据变动,导致相关的历史记录数据产生变动的解决方案
    发布一个RSS辅助类
    感谢jquery和firebug,让我也终于敢于写javascript了
    DevExpress ASPxGridView 使用文档四:数据源
    DevExpress ASPxGridView 使用文档六:模板
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/12655557.html
Copyright © 2011-2022 走看看