zoukankan      html  css  js  c++  java
  • Luogu P3601 签到题

    ( ext{Problem})

    签到题

    ( ext{Analysis})

    区间筛积性函数,如 (varphi)
    因为 (r-l le 10^6),所以这个问题就是非常经典的了
    比较常见的技巧
    (varphi(n)=nprod(1-frac 1 p))
    ([l,r]) 以内的数若不为素数分解质因数后最小的必然小于 (sqrt r)
    (sqrt r) 以内的素数算贡献即可
    顺便除掉素数,就可以找到 (sqrt r) 以外的素数

    ( ext{Code})

    #include<cstdio>
    #include<cmath>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    
    const int N = 1e6 + 5;
    const LL P = 666623333;
    int tot;
    LL l, r, prime[N], num[N], vis[N];
    
    void getprime(int Mx)
    {
    	vis[1] = 1;
    	for(int i = 2; i <= Mx; i++)
    	{
    		if (!vis[i]) prime[++tot] = i;
    		for(int j = 1; j <= tot && prime[j] * i <= Mx; j++)
    		{
    			vis[prime[j] * i] = 1;
    			if (i % prime[j] == 0) break;
    		}
    	}
    }
    
    LL solve()
    {
    	for(int i = 1; i <= r - l + 1; i++) vis[i] = num[i] = l + i - 1;
    	for(int i = 1; i <= tot && prime[i] <= r; i++)
    	{
    		for(LL j = max(1LL, l / prime[i]); j * prime[i] <= r; j++)
    		if (j * prime[i] >= l) 
    		{
    			vis[j * prime[i] - l + 1] = vis[j * prime[i] - l + 1] - vis[j * prime[i] - l + 1] / prime[i];
    			while (num[j * prime[i] - l + 1] % prime[i] == 0)
    				num[j * prime[i] - l + 1] /= prime[i];
    		}
    	}
    	for(int i = 1; i <= r - l + 1; i++)
    	if (num[i] > 1) vis[i] = vis[i] - vis[i] / num[i];
    	LL ans = 0;
    	for(int i = 1; i <= r - l + 1; i++) ans = (ans + (l + i - 1 - vis[i])) % P;
    	return ans;
    }
    
    int main()
    {
    	scanf("%lld%lld", &l, &r);
    	getprime(sqrt(r) + 5);
    	printf("%lld
    ", solve());
    }
    

    ( ext{Addition})

    区间筛 (mu)
    同样的有 (r-l le 10^6)
    同理,利用积性函数的性质即可

    inline void solve_u(ll l, ll r)
    {
    	for(int i = 1; i <= r - l + 1; i++) mu[i] = 1, num[i] = i + l - 1;
    	for(int i = 1; i <= totp && prime[i] <= r; i++)
    	{
    		for(ll j = max(l / prime[i], 1ll); j * prime[i] <= r; j++)
    		if (j * prime[i] >= l)
    		{
    			if (j % prime[i] == 0) mu[j * prime[i] - l + 1] = 0;
    			else mu[j * prime[i] - l + 1] *= -1, num[j * prime[i] - l + 1] /= prime[i];
    		}
    	}
    	for(int j = 1; j <= r - l + 1; j++)
    	if (mu[j] != 0 && num[j] != 1) mu[j] *= -1;
    }
    
  • 相关阅读:
    使用纯资源DLL文件实现多语言菜单、界面文字、Tooltips等[转]
    用VC++打造有多语言菜单的应用程序[转]
    VC2008以资源形式实现多语言版本[转]
    GetWindowRect与GetClientRect 的区别[转]
    MFC拆分窗口及它们之间的数据交换[转]
    【排序算法】(7)快速排序
    【排序算法】(4)归并排序
    【排序算法】(3)插入排序
    【排序算法】(8)希尔排序
    【排序算法】(2)冒泡排序
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/14977494.html
Copyright © 2011-2022 走看看