zoukankan      html  css  js  c++  java
  • 紫书 例题 10-27 UVa 10214(欧拉函数)

    只看一个象限简化问题,最后答案乘4+4

    象限里面枚举x, 在当前这条固定的平行于y轴的直线中

    分成长度为x的一段段。符合题目要求的点gcd(x,y) = 1

    那么第一段1<= y <= x,个数为phi(x)个,即是x的欧拉函数值

    第二段x+1 <= y <= 2x, 因为gcd(x + i, x) = gcd(x, i)

     接下来同理

    一直到最后一段

    kx + 1 <= y <= b要单独一个个算,因为最后一段的长度不一定为x

    感觉这道题算每一条直线时分成长度为x的一段段很巧妙,不好想到

    #include<cstdio>
    #include<cmath>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    using namespace std;
    
    typedef long long ll;
    
    int phi(int n)
    {
    	int ans = n;
    	for(int i = 2; i * i <= n; i++)
    		if(n % i == 0)
    		{
    			ans = ans / i * (i - 1);
    			while(n % i == 0) n /= i;
    		}	
    	if(n > 1) ans = ans / n * (n - 1);
    	return ans;
    }
    
    
    int gcd(int a, int b) { return !b ? a : gcd(b, a % b); }
    
    ll f(int a, int b)
    {
    	ll ans = 0;
    	REP(x, 1, a + 1)
    	{
    		int k = b / x;
    		ans += phi(x) * k;
    		REP(y, k*x + 1, b + 1)
    			if(gcd(x, y) == 1)
    				ans++;	
    	}	
    	return 4 * ans + 4;
    }
    
    int main()
    {
    	int a, b;
    	while(~scanf("%d%d", &a, &b) && a)
    	{
    		ll K = f(a, b);
    		ll N = (ll)(2 * a + 1) * (2 * b + 1) - 1;
    		printf("%.7lf
    ", (double)K / N);
    	} 
    	return 0;
    }
  • 相关阅读:
    获取字符串出现的次数
    手机号码正则表达式验证
    DOM: EVENT FLOW
    AsyncCallback 异步回调委托
    高德地图
    我的json
    Arrow function restore
    constructor&object 的联系与对比
    for each/in/of的解释and example
    program发展史及以后预测
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819492.html
Copyright © 2011-2022 走看看