• 约数个数和「SDOI2015」


    题意

    已知(n,m),求(sum^n_asum^m_b d(ab)),其中(d(x))表示(x)的约数个数。


    思路

    结论:(d(nm)=sum_{i|n}sum_{j|m}[gcd(i,j)==1])。(证明见后)

    由此可得原式等价于(sum^n_asum^m_bsum_{i|n}sum_{j|m}[gcd(i,j)==1])

    (sum^n_isum^m_jfrac{n}{i}frac{m}{j}[gcd(i,j)==1])

    (f(d)=sum^n_isum^m_jfrac{n}{i}frac{m}{j}[gcd(i,j)==d])

    (F(d)=sum^n_isum^m_jfrac{n}{i}frac{m}{j}[gcd(i,j)|d]=sum^{frac{n}{d}}_isum^{frac{m}{d}}_j frac{n}{id}frac{m}{jd})

    那么有(F(d)=sum_{d|i} f(i))

    所以(f(i)=sum_{i|d}F(d)mu{frac{d}{i}})

    代码

    
    #include <bits/stdc++.h>
    
    using namespace std;
    
    namespace StandardIO {
    
    	template<typename T> inline void read (T &x) {
    		x=0;T f=1;char c=getchar();
    		for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
    		for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
    		x*=f;
    	}
    	template<typename T> inline void write (T x) {
    		if (x<0) putchar('-'),x=-x;
    		if (x>=10) write(x/10);
    		putchar(x%10+'0');
    	}
    
    }
    
    using namespace StandardIO;
    
    namespace Solve {
    	
    	const int N=50001;
    	
    	int n,top;
    	int a,b;
    	int isprime[N],prime[N];
    	long long mu[N],pre[N];
    	
    	inline void init () {
    		mu[1]=1;
    		for (register int i=2; i<=N; ++i) {
    			if (!isprime[i]) {
    				prime[++top]=i,mu[i]=-1;
    			}
    			for (register int j=1; j<=top&&i*prime[j]<=N; ++j) {
    				isprime[i*prime[j]]=1;
    				if (i%prime[j]==0) {
    					mu[i*prime[j]]=0;
    					break;
    				}
    				mu[i*prime[j]]=-mu[i];
    			}
    		}
    		for (register int i=1; i<=N; ++i) mu[i]+=mu[i-1];
    		for (register int x=1; x<=N; ++x) {
    			for (register int i=1,r; i<=x; i=r+1) {
    				r=x/(x/i);
    				pre[x]+=(long long)(x/i)*(r-i+1);
    			}
    		}
    	}
    	inline long long calc (int m,int n) {
    		long long sum=0;
    		for (register int i=1,r; i<=min(m,n); i=r+1) {
    			r=min(n/(n/i),m/(m/i));
    			sum+=pre[n/i]*pre[m/i]*(mu[r]-mu[i-1]);
    		}
    		return sum;
    	}
    
    	inline void MAIN () {
    		init();
    		read(n);
    		for (register int i=1; i<=n; ++i) {
    			read(a),read(b);
    			write(calc(a,b)),putchar('
    ');
    		}
    	}
    	
    }
    
    int main () {
    	Solve::MAIN();
    }
    

    证明

    orz Siyuan

    搜狗截图20190814211034.png

  • 相关阅读:
    强弱类型 静态语言 动态语言 || 脚本语言
    mysql版本升级问题处理
    word
    IntelliJ IDEA 插件
    dubbo
    spring源码构建
    zookeeper 本地多线程模拟分布式事务控制及配置中心
    一次性关闭所有的Activity
    可能以后用得到得东西
    Thread.sleep还是TimeUnit.SECONDS.sleep
  • 原文地址:https://www.cnblogs.com/ilverene/p/11354559.html
Copyright © 2020-2023  润新知