zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 206 E

    题目描述

    求区间([L, R])中, 满足:

    • (L le x, y le R)
    • (gcd(x, y) e 1, dfrac{x}{g} e 1, dfrac{y}{g} e 1)

    ((x, y))数量. ((1 le L le R le 10^6))

    Solution

    首先,直接求满足要求的方案不容易求,可以转化为求不满足要求的方案数
    不满足要求的方案数可以分为两种:

    • (g = 1) :
      即求 ([L, R]) 区间内,(gcd(x, y) = 1)((x, y)) 数量
      即: (sumlimits_{x = L} ^ Rsumlimits_{y = L} ^ R [gcd(x, y) = 1])
      带入公式: (sumlimits_{d | n} mu (d) = [n = 1])
      得: (sumlimits_{x = L} ^ Rsumlimits_{y = L} ^ Rsumlimits_{d | gcd(x, y)} mu (d))
      = (sumlimits_{d = 1} ^ R mu (d) * leftlfloordfrac{R}{d} - dfrac{L - 1}{d} ight floor * leftlfloordfrac{R}{d} - dfrac{L - 1}{d} ight floor)
    • (g != 1) :
      处理 (dfrac{x}{g} = 1;or; dfrac{y}{g} = 1) 的情况
      (x < y) , 若符合上述情况, 即 (x | y)
      枚举 (x) , 计算 (x) 的倍数个数即可.

    注: (L = 1) 时, ((1, 1)) 被重复计算两次,要特殊处理.

    Sample Code (C++)
    int L, R;
    int primes[N], cnt, mu[N];
    bool st[N];
    
    void e_prime()
    {
    	mu[1] = 1;
    	for(int i = 2; i < N; ++ i)
    	{
    		if(!st[i]) 
    		{
    			primes[cnt ++] = i;
    			mu[i] = -1;
    		}
    		for(int j = 0; i * primes[j] < N; ++ j)
    		{
    			st[primes[j] * i] = 1;
    			if(i % primes[j] == 0) break;
    			mu[i * primes[j]] = -mu[i]; 
    		}
    	}
    }
    
    int main()
    {
    	e_prime();
    	IOS; cin >> L >> R;
    	LL res = 0;
    	// g = 1
    	for(int i = 1; i <= R; ++ i)
    	{
    		LL tmp = (R / i - (L - 1) / i);
    		res += mu[i] * tmp * tmp;
    	}
    	//g != 1
    	for(int i = max(2, L); i <= R; ++ i) res += (R / i - 1) * 2;
    	res = (LL)(R - L) * (R - L + 1) - res;
    	if(L == 1) res ++;
    	cout << res << endl;
    	return 0;
    } 
    
  • 相关阅读:
    mybatis中的延迟加载
    MyBatis的mapper
    MyBatis的resultMap
    mybatis入门
    mybatis中的#和$的区别(转)
    操作日志记录
    SpringMVC中的异常处理集锦
    vue.js的package.json相关问题解惑
    git的常用操作指令
    http协议参数详解
  • 原文地址:https://www.cnblogs.com/ooctober/p/14966691.html
Copyright © 2011-2022 走看看