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;
    } 
    
  • 相关阅读:
    [CTSC2008]网络管理
    [HNOI/AHOI2018]转盘
    [HAOI2015]树上染色
    [CTSC2017]吉夫特
    [CTSC2011]幸福路径
    Comet OJ
    2019各省省选试题选做
    HNOI2019 简要题解
    HNOI2019游记
    JOISC2019 简要题解
  • 原文地址:https://www.cnblogs.com/ooctober/p/14966691.html
Copyright © 2011-2022 走看看