zoukankan      html  css  js  c++  java
  • 洛谷4388 付公主的矩形(数论,数学)

    好题!!!
    我比较菜,没有推出来,还是看了别人的题解。对于一个nm的矩阵且gcd(n,m)==1,从1,1到(n,m)肯定只穿过了n+m-1个矩阵,因为中间没有经过整点。同时,对于任意n,m经过的矩阵就相当于q=n/gcd(n,m),w=m/gcd(n,m),那么对于qw的矩阵,穿过了q+w-1个矩阵,那么对于nm的矩阵,经过了(q+w-1)gcd(n,m)个矩阵,那么就相当于n*m的矩阵经过了n+m-gcd(n,m)个矩阵。那么答案就是Σni+j-gcd(i,j)。由于这玩意的复杂度很高,到了n²lnn,一分都骗不到,我们考虑优化。记N=i+j-gcd(i,j),d=gcd(i,j),将左边的式子两边除以d,假设得到的式子是N'=i'+j'-1。所以gcd(i',j')gcd(i',N'+1-j')gcd(i',N'+1)1,那么对于这个N'来说,所得答案就是φ(N'+1),那么答案就是Σ(d|n)φ(d+1);

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int N = 1e6 + 5;
    
    int n, l = 0, ans = 0, pri[N], phi[N];
    bool np[N];
    
    inline void sieve() {
    	phi[1]=0;
    	for(int i=2;i<=n+1;i++){
    		if(!np[i]) np[i]=1,phi[i]=i-1,pri[++l]=i;
    		for(int j=1;i*pri[j]<=n+1;j++){
    			np[i*pri[j]]=1;
    			if(i%pri[j]==0){phi[i*pri[j]]=phi[i]*pri[j];break;}
    			phi[i*pri[j]]=phi[i]*phi[pri[j]];
    		}
    	} 
    } 
    int main() {
    	scanf("%d", &n);
    	sieve();
    	for(int i = 1; i <= n; i++)
    		if(n % i == 0) ans += phi[i + 1];
    	printf("%d
    ", (ans + 1) / 2);
    	return 0;
    }
    
  • 相关阅读:
    模拟100 题解
    模拟99 题解
    模拟98 题解
    模拟97 题解
    模拟96 题解
    模拟95 题解
    模拟94 题解
    模拟93 题解
    模拟92 题解
    Django-- 多数据库联用
  • 原文地址:https://www.cnblogs.com/BLUE-EYE/p/9574840.html
Copyright © 2011-2022 走看看