• luogu2257 YY的GCD


    题目链接

    problem

    给出一个(n,m(n,mle 10^7)),求(sumlimits_{i=1}^nsumlimits_{j=1}^mgcd(i,j)in P)
    P表示全部素数的集合。
    (T,(Tle 10000))组询问

    solution

    枚举因数

    [原式=sumlimits_{din P} sumlimits_{i=1}^{frac{n}{d}}sumlimits_{j=1}^{frac{m}{d}}epsilon(gcd(i,j)=1) ]

    因为(epsilon=1*mu)

    [所以上式=sumlimits_{din P} sumlimits_{i=1}^{frac{n}{d}}sumlimits_{j=1}^{frac{m}{d}}sumlimits_{k|i,k|j}mu(k)\ =sumlimits_{din P}sumlimits_{k=1}^{frac{min(n,m)}{d}}mu(k)lfloorfrac{n}{dk} floorlfloorfrac{m}{dk} floor ]

    (t=dk)

    原式=$$sumlimits_{t=1}^{min(n,m)}lfloorfrac{n}{t} floor lfloorfrac{m}{t} floorsumlimits_{din P,d|t}mu(frac{t}{d})$$

    发现前面这一块数论分块就好了,后面就提前预处理出来,求个前缀和。

    预处理复杂度(O(nloglogn)),单次询问复杂度(O(sqrt{n}))

    code

    	/*
    	* @Author: wxyww
    	* @Date:   2020-01-20 19:08:26
    	* @Last Modified time: 2020-01-20 19:18:39
    	*/
    	#include<cstdio>
    	#include<iostream>
    	#include<cstdlib>
    	#include<cstring>
    	#include<algorithm>
    	#include<queue>
    	#include<vector>
    	#include<ctime>
    	using namespace std;
    	typedef long long ll;
    	const int N = 10000010;
    	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;
    	}
    	int mu[N],pri[N],tot,vis[N];
    	void pre() {
    		mu[1] = 1;
    		for(int i = 2;i < N;++i) {
    			if(!vis[i]) pri[++tot] = i,mu[i] = -1;
    			for(int j = 1;j <= tot && 1ll * i * pri[j] < N;++j) {
    				vis[i * pri[j]] = 1;
    				if(i % pri[j]) mu[i * pri[j]] = -mu[i];
    				else {
    					mu[i * pri[j]] = 0;break;
    				}
    			}
    		}
    	}
    	int f[N];
    	int main() {
    		pre();
    
    		for(int i = 1;i <= tot;++i) {
    			int js = 1;
    			for(int k = pri[i];k < N;k += pri[i],++js) {
    				f[k] += mu[js];
    			}
    		}
    
    		for(int i = 1;i < N;++i) f[i] += f[i - 1];
    
    		int T = read();
    		while(T--) {
    			int n = read(),m = read();
    			ll ans = 0;
    			for(int l = 1,r;l <= min(n,m);l = r + 1) {
    				r = min(n / (n / l),m / (m / l));
    				ans += 1ll * (n / l) * (m / l) * (f[r] - f[l - 1]);
    			}
    			printf("%lld
    ",ans);
    		}
    		return 0;
    	}
    
  • 相关阅读:
    nginx路径详解
    负载均衡
    http中消息头的安全配置及工作原理
    Tomcat的ErrorPage实现原理分析及阀门ErrorReportValve
    Tomcat中Logger组件
    NIO在Tomcat中的应用
    vue中强制生效css样式
    k8s中的Ingress
    xhr.withCredentials与 CORS 什么关系
    Redis Cluster集群
  • 原文地址:https://www.cnblogs.com/wxyww/p/luogu2257.html
Copyright © 2020-2023  润新知