zoukankan      html  css  js  c++  java
  • test20181101 怜香惜玉 和 BZOJ2226 LCMSum

    怜香惜玉

    分析

    观察(直到考试最后一小时我才尝试打表)发现若(gcd(x,i)=1),则(gcd(x,x-i)=1),所以是对称的。

    那么又由于乘了2,所以(f(x)=x)

    然后打个快速幂,求个前缀和就行了。

    时间复杂度(O(n log n))

    co int MAXN=1e6+1,mod=998244353;
    
    int qpow(int x,int k)
    {
    	int res=1;
    	while(k)
    	{
    		if(k&1)
    			res=(ll)res*x%mod;
    		x=(ll)x*x%mod,k>>=1;
    	}
    	return res;
    }
    
    int ans[MAXN];
    
    int main()
    {
    	int T,k;
    	read(T);read(k);
    	for(int i=1;i<MAXN;++i)
    	{
    		ans[i]=qpow(i,k);
    		(ans[i]+=ans[i-1])%=mod;
    	}
    	while(T--)
    	{
    		printf("%d
    ",ans[read<int>()]);
    	}
        return 0;
    }
    

    拓展

    L巨:这题是套路,经常用到。

    然而由于L巨太巨了,所以L巨还是帮我把这个式子用莫比乌斯反演证明出来了。

    要证明的是

    [sum_{i=0}^{n}i cdot [gcd(i,n)=1] = frac{(varphi(n) + e(n)) cdot n}{2} ]

    加上一个e是因为按题意phi(1)=2

    证明

    [左边 \ =sum_{i=0}^{n} i cdot sum_{d|i且d|n} mu(d) \ =sum_{d|n} mu(d) sum_{i=0}^{lfloor frac{n}{d} floor} d cdot i \ =sum_{d|n} mu(d) cdot d cdot frac{frac{n}{d}(frac{n}{d}+1)}{2} \ =frac{n}{2}(mu*id+e)(n) \ =frac{n cdot (varphi(n) + e(n))}{2} \ =右边 ]

    解释

    第三步d整除n,所以去掉了下取整符号,转化为等差数列求和。

    倒数第二步在消掉分子分母中同时出现的数。

    倒数第一步,由于有

    [mu * 1 = e \ varphi * 1 = id ]

    所以交叉卷积,消去1得到

    [mu * id = varphi ]

    LCMSum

    给定(n(n leq 10^6)),求

    [sum_{i=1}^{n} extrm{lcm}(i,n) ]

    (T(T leq 3 imes 10^5))组询问。

    分析

    https://blog.sengxian.com/solutions/bzoj-2226?tdsourcetag=s_pcqq_aiomsg

    [sum_{i=1}^{n} extrm{lcm}(i,n) \ =sum_{i=1}^{n}frac{i cdot n}{gcd(i,n)}\ =n sum_{d|n}frac{1}{d}sum_{i=1}^{n}[gcd(i,n)=d] cdot i\ =n sum_{d|n}frac{1}{d}sum_{i=1}^{frac{n}{d}}[gcd(i,frac{n}{d})=1] cdot i cdot d \ = n sum_{d|n} sum_{i=1}^{frac{n}{d}} [gcd(i,frac{n}{d})=1] cdot i ]

    后半部分参照上一题,可得

    [原式 =n sum_{d|n} frac{(varphi(n) + e(n)) cdot n}{2} \ =frac{n}{2} sum_{d|n} (varphi(n) + e(n)) cdot n ]

    现在的这个后面的式子(O(n))线性筛后,枚举倍数(O(n ln n))预处理。

    然后就能(O(1))回答每次询问。

    时间复杂度(O(n + n ln n + T))

    co int MAXN=1e6+7;
    int prime[MAXN],pcnt;
    int phi[MAXN];
    ll f[MAXN];
    
    void linear()
    {
    	prime[1]=1;
    	phi[1]=1;
    	for(int i=2;i<MAXN;++i)
    	{
    		if(!prime[i])
    		{
    			prime[++pcnt]=i;
    			phi[i]=i-1;
    		}
    		for(int j=1;j<=pcnt&&i*prime[j]<MAXN;++j)
    		{
    			prime[i*prime[j]]=1;
    			phi[i*prime[j]]=phi[i]*phi[prime[j]];
    			if(i%prime[j]==0)
    			{
    				phi[i*prime[j]]=phi[i]*prime[j];
    				break;
    			}
    		}
    	}
    	for(int i=1;i<MAXN;++i)
    		for(int j=i;j<MAXN;j+=i)
    			f[j]+=(ll)phi[i]*i;
    }
    
    ll solve(int n)
    {
    	return (f[n]+1)*n/2;
    }
    
    int main()
    {
    	linear();
    	int T=read<int>();
    	while(T--)
    	{
    		printf("%lld
    ",solve(read<int>()));
    	}
        return 0;
    }
    
    静渊以有谋,疏通而知事。
  • 相关阅读:
    Northwind测试学习用数据库
    DataTables在回调方法中使用api
    DataTables获取表单输入框数据
    DataTables选择行并删除(删除单行)
    DataTables选择多行
    DataTables给每一列添加下拉框搜索
    AngularJS 父子控制器
    更改AngularJS的语法解析符号
    AngularJS中的控制器示例_3
    AngularJS中的控制器示例_2
  • 原文地址:https://www.cnblogs.com/autoint/p/9892650.html
Copyright © 2011-2022 走看看