zoukankan      html  css  js  c++  java
  • 51nod1237 最大公约数之和

    题目链接

    题意

    其实就是求

    [sumlimits_{i=1}^nsumlimits_{j=1}^ngcd(i,j) ]

    思路

    建议先看一下此题的一个弱化版

    推一下式子

    [sumlimits_{i=1}^nsumlimits_{j=1}^ngcd(i,j) ]

    [= sumlimits_{k=1}^nksumlimits_{i=1}^nsumlimits_{j=1}^n[gcd(i,j)=k] ]

    [=sumlimits_{k=1}^nksumlimits_{i=1}^{frac{n}{k}}sumlimits_{j=1}^{frac{n}{k}}[gcd(i,j)=1] ]

    [=sumlimits_{k=1}^nksumlimits_{i=1}^{frac{n}{k}}2varphi(i)-1 ]

    (phi(i)=varphi(1)+varphi(2)+...+varphi(i))

    则原式

    [=sumlimits_{i=1}^ni(2phi(frac{n}{i})-1) ]

    然后就可以数论分块啦。

    至于怎么比较快的求(phi(i)),基本的杜教筛喽。。

    代码

    //loj6074
    /*
    * @Author: wxyww
    * @Date:   2019-03-30 12:43:48
    * @Last Modified time: 2019-03-30 19:43:10
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<vector>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    const int mod = 1e9 + 7,N = 1000000 + 100,inv2 = (mod + 1) / 2;
    
    ll read() {
    	ll x=0,f=1;char c=getchar();
    	while(c<'0'||c>'9') {
    		if(c=='-') f=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9') {
    		x=x*10+c-'0';
    		c=getchar();
    	}
    	return x*f;
    }
    map<ll,ll>ma;
    ll n,sum[N];
    int dis[N],vis[N],js;
    int dls(ll x) {
    	if(x <= 1000000) return sum[x];
    	if(ma[x]) return ma[x];
    	ll ret = 1ll * x % mod * ((x + 1) % mod) % mod * inv2 % mod;
    	for(ll l = 2,r;l <= x;l = r + 1) {
    		r = x / (x / l);
    		ret -= 1ll * (r - l + 1) % mod * dls(x / l) % mod;
    		ret = (ret + mod) % mod;
    	}
    	return ma[x] = ret;
    }
    void pre() {
    	sum[1] = 1;vis[1] = 1;
    	int NN = min(n,1000000ll);
    	for(int i = 2;i <= NN;++i) {
    		if(!vis[i]) {
    			dis[++js] = i;
    			sum[i] = i - 1;
    		}
    		for(int j = 1;j <= js && dis[j] * i <= NN;++j) {
    			vis[dis[j] * i] = 1;
    			if(i % dis[j] == 0) {
    				sum[dis[j] * i] = sum[i] * dis[j] % mod;	break;
    			}
    			sum[dis[j] * i] = (dis[j] - 1) * sum[i] % mod;
    		}
    		sum[i] += sum[i - 1];
    		sum[i] %= mod;
    	}
    	
    }
    signed main() {
    	n = read();
    	pre();
    	ll ans = 0;
    	for(ll l = 1,r;l <= n;l = r + 1) {
    		r = n / (n / l);
    		ans = (ans + (1ll * (r - l + 1) % mod * ((r + l) % mod) % mod * inv2 % mod) % mod * ((2ll * dls(n / l) % mod) - 1 + mod) % mod) % mod;  
    	}
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    1058 A+B in Hogwarts (20)
    1046 Shortest Distance (20)
    1061 Dating (20)
    1041 Be Unique (20)
    1015 Reversible Primes (20)(20 分)
    pat 1027 Colors in Mars (20)
    PAT 1008 Elevator (20)
    操作系统 死锁
    Ajax的get方式传值 避免& 与= 号
    让IE浏览器支持CSS3表现
  • 原文地址:https://www.cnblogs.com/wxyww/p/51nod1237.html
Copyright © 2011-2022 走看看