zoukankan      html  css  js  c++  java
  • P3768 简单的数学题 [杜教筛,莫比乌斯反演]

    [sum_{i=1}^{n}sum_{j=1}^{n} ijgcd(i,j) ]

    [=sum_{d=1}^{n} d sum_{i=1}^{n}sum_{j=1}^{n} ij[gcd(i,j)==d] ]

    [=sum_{d=1}^{n} d^3 sum_{i=1}^{lfloorfrac{n}{d} floor} sum_{j=1}^{lfloorfrac{n}{d} floor} ij[gcd(i,j)==1] ]

    [=sum_{d=1}^{n} d^3 sum_{i=1}^{lfloorfrac{n}{d} floor} sum_{j=1}^{lfloorfrac{n}{d} floor} ij[gcd(i,j)==1] ]

    因为 (sum_{t|n} mu(t) = [n == 1])
    所以

    [=sum_{d=1}^{n} d^3 sum_{i=1}^{lfloorfrac{n}{d} floor} sum_{j=1}^{lfloorfrac{n}{d} floor} ij sum_{t|gcd(i,j)} mu(t) ]

    [=sum_{d=1}^{n} d^3 sum_{t=1}^{lfloorfrac{n}{d} floor} mu(t) t^2 sum_{i=1}^{lfloorfrac{n}{td} floor} sum_{j=1}^{lfloorfrac{n}{td} floor} ij ]

    (sum_x = sum_{i=1}^{x})

    则原式等同于

    [=sum_{d=1}^{n} d^3 sum_{t=1}^{lfloorfrac{n}{d} floor} mu(t) t^2 (sum_{lfloor frac{n}{td} floor})^2 ]

    (T=td)

    [=sum_{T=1}^{n} T^2 (sum_{lfloor frac{n}{T} floor})^2 sum_{d|t} mu (frac{T}{d}) d ]

    因为

    [sum_{d|n} frac{mu(d)}{d} = frac{varphi(n)}{n} ]

    根据狄利克雷卷积

    [id(x) = x , id * mu = varphi ]

    那么这个柿子变成了

    [sum_{T=1}^{n}T^2 varphi(T) (sum_{lfloor frac{n}{T} floor})^2 ]

    然后我们本身知道 形如 (lfloor frac{n}{T} floor) 之类的玩意可以数论分块

    然后 (f_x = x^2 varphi(x)) 的前缀和

    (s_x)(f_x) 的前缀和,然后考虑 (g) 函数

    然后我们知道

    [sum_{d|n} varphi(d) = n ]

    考虑 (g) 函数为 (g_i = i^2)

    [(g*f)(i) = sum_{d|i} d^2 varphi (d) frac{i^2}{d^2} = sum_{d|i}varphi (d) i^2 = i^3 ]

    [s_n = sum_{i=1}^{n} i^3 - sum_{i=2}^{n} i^2 s_{frac{n}{i}} ]

    因为

    [sum_{i=1}^{n}i^3 = (sum_{i=1}^{n}i)^2 ]

    [sum_{i=1}^{n}i^2 = frac{n(n+1)(2n+1)}{6} ]

    Q.E.D.

    杜教筛一手,这题没了。

    // powered by c++11
    // by Isaunoya
    #include<bits/stdc++.h>
    #define rep(i , x , y) for(register int i = (x) ; i <= (y) ; ++ i)
    #define Rep(i , x , y) for(register int i = (x) ; i >= (y) ; -- i)
    using namespace std ;
    using db = double ;
    using ll = long long ;
    using uint = unsigned int ;
    #define int long long
    using pii = pair < int , int > ;
    #define ve vector
    #define Tp template
    #define all(v) v.begin() , v.end()
    #define sz(v) ((int)v.size())
    #define pb emplace_back
    #define fir first
    #define sec second
    // the cmin && cmax
    Tp < class T > void cmax(T & x , const T & y) { if(x < y) x = y ; }
    Tp < class T > void cmin(T & x , const T & y) { if(x > y) x = y ; }
    // sort , unique , reverse
    Tp < class T > void sort(ve < T > & v) { sort(all(v)) ; }
    Tp < class T > void unique(ve < T > & v) { sort(all(v)) ; v.erase(unique(all(v)) , v.end()) ; }
    Tp < class T > void reverse(ve < T > & v) { reverse(all(v)) ; }
    const int SZ = 0x191981 ;
    struct FILEIN {
    	~ FILEIN () {} char qwq[SZ] , * S = qwq , * T = qwq , ch ;
    	char GETC() { return (S == T) && (T = (S = qwq) + fread(qwq , 1 , SZ , stdin) , S == T) ? EOF : * S ++ ; }
    	FILEIN & operator >> (char & c) { while(isspace(c = GETC())) ; return * this ; }
    	FILEIN & operator >> (string & s) {
    		while(isspace(ch = GETC())) ; s = "" + ch ;
    		while(! isspace(ch = GETC())) s += ch ; return * this ;
    	}
    	Tp < class T > void read(T & x) {
    		bool sign = 1 ; while((ch = GETC()) < 0x30) if(ch == 0x2d) sign = 0 ;
    		x = (ch ^ 0x30) ; while((ch = GETC()) > 0x2f) x = x * 0xa + (ch ^ 0x30) ;
    		x = sign ? x : -x ;
    	}
    	FILEIN & operator >> (int & x) { return read(x) , * this ; }
    	FILEIN & operator >> (signed & x) { return read(x) , * this ; }
    	FILEIN & operator >> (unsigned & x) { return read(x) , * this ; }
    } in ;
    struct FILEOUT { const static int LIMIT = 0x114514 ;
    	char quq[SZ] , ST[0x114] ; signed sz , O ;
    	~ FILEOUT () { sz = O = 0 ; }
    	void flush() { fwrite(quq , 1 , O , stdout) ; fflush(stdout) ; O = 0 ; }
    	FILEOUT & operator << (char c) { return quq[O ++] = c , * this ; }
    	FILEOUT & operator << (string str) {
    		if(O > LIMIT) flush() ; for(char c : str) quq[O ++] = c ; return * this ;
    	}
    	Tp < class T > void write(T x) {
    		if(O > LIMIT) flush() ; if(x < 0) { quq[O ++] = 0x2d ; x = -x ; }
    		do { ST[++ sz] = x % 0xa ^ 0x30 ; x /= 0xa ; } while(x) ;
    		while(sz) quq[O ++] = ST[sz --] ; return ;
    	}
    	FILEOUT & operator << (int x) { return write(x) , * this ; }
    	FILEOUT & operator << (signed x) { return write(x) , * this ; }
    	FILEOUT & operator << (unsigned x) { return write(x) , * this ; }
    } out ;
    
    int n , p ;
    const int maxn = 5e6 + 10 ;
    int phi[maxn + 5] ;
    int iv2 , iv6 ;
    int qpow(int x , int y) {
    	int res = 1 ;
    	for( ; y ; y >>= 1 , x = x * x % p)
    		if(y & 1)
    			res = res * x % p ;
    	return res ;
    }
    int sum(int x) {
    	x = x - (x / p) * p ;
    	return (x + 1) * x % p * iv2 % p ;
    }
    int sum2(int x) {
    	x = x - (x / p) * p ;
    	return (x + 1) * x % p * (x + x + 1) % p * iv6 % p ;
    }
    
    unordered_map < int , int > _phi ;
    int s(int x) {
    	if(x <= maxn) return phi[x] ;
    	if(_phi[x]) return _phi[x] ;
    	int ans = sum(x) ;
    	ans = ans * ans % p ;
    	for(int l = 2 , r ; l <= x ; l = r + 1) {
    		r = x / (x / l) ;
    		ans = (ans - (sum2(r) - sum2(l - 1) + p) % p * s(x / l) % p + p) % p ;
    	}
    	return _phi[x] = ans ;
    }
    signed main() {
    #ifdef _WIN64
    	freopen("testdata.in" , "r" , stdin) ;
    #else
    	ios_base :: sync_with_stdio(false) ;
    	cin.tie(nullptr) , cout.tie(nullptr) ;
    #endif
    // code begin.
    	in >> p >> n ;
    	iv2 = qpow(2 , p - 2) ;
    	iv6 = qpow(6 , p - 2) ;
    	phi[1] = 1 ;
    	for(int i = 2 ; i <= maxn; i ++) {
    		if(phi[i]) 
    			continue ;
    		for(int j = i ; j <= maxn ; j += i) {
    			if(! phi[j]) 
    				phi[j] = j ;
    			phi[j] = phi[j] / i * (i - 1) ;
    		}
    	}
    	for(int i = 1 ; i <= maxn ; i ++) 
    		phi[i] = (phi[i - 1] + 1ll * i * i % p * phi[i] % p) % p ;
    	int ans = 0 ;
    	for(int l = 1 , r ; l <= n ; l = r + 1) {
    		r = n / (n / l) ;
    		int k = sum(n / l) ;
    		k = k * k % p ;
    		ans = (ans + (s(r) - s(l - 1) + p) % p * k % p) % p ;
    	}
    	out << ans << '
    ' ;
    	return out.flush() , 0 ;
    // code end.
    }
    
  • 相关阅读:
    UWP 常用文件夹
    UWP 判断Windows10系统版本
    UWP 图片缩放
    Windows 10「设置」应用完整MS-Settings快捷方式汇总
    UWP 用Thumb 控件仿制一个可拖动悬浮 Button
    【mp3】洗脑循环了!龙珠超 自在极意功 【究极の圣戦】串田アキラ 背景纯音乐
    工作三年后的总结
    css3 移动端 开关效果
    js 移动端上拉加载下一页通用方案
    【我的上传番剧/电影】收藏夹
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12246398.html
Copyright © 2011-2022 走看看