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

    这里用到了一些数论知识

    首先素因子都大于M等价与M! 互质

    然后又因为当k与M!互质且k>M!时当且仅当k mod M! 与M!互质(欧几里得算法的原理)

    又因为N>=M, 所以N!为M!的倍数

    所以只要求1到M!中与M!互质的数的个数,在乘上N!/M!

    可以理解为每一块M!有这么多,然而N!中有很多块M!,所以乘上N!/M!

    然后根据phifac[n] = phi[n!] = n!(1-1/p1)(1-1/p2)......(1-1/k)的定义可以得出

    当n为质数的时候 phifac[n] = (n-1) * phifac[n-1]

    当n不为质数的时候 phifac[n] = n * phifac[n-1]

    (拿笔根据定义手算一下就可以得出)
    边界是phifac[1] = phifac[2] = 1

    书中问到为什么phifac[1] = 1

    实际上是因为如果m=1,那么除1以外的所有数的素因子都大于1(素因子最小为2)

    所以当m=1时后面乘的时候ans是为1的,如果ans为0的话最终答案为0

    而实际上答案为N!-1

    根据定义是phifac[1]=0,但根据这道题实际情况phifac[1]=1

    最后注意中间结果可能溢出,所以用long long

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    using namespace std;
    
    const int MAXN = 11234567;
    const int MOD = 100000007;
    bool is_prime[MAXN];
    vector<int> prime;
    int phifac[MAXN];
    
    void init()
    {
    	memset(is_prime, true, sizeof(is_prime));
    	is_prime[0] = is_prime[1] = false;
    	REP(i, 2, MAXN)
    	{
    		if(is_prime[i]) prime.push_back(i);
    		REP(j, 0, prime.size())
    		{
    			if(i * prime[j] > MAXN) break;
    			is_prime[i*prime[j]] = false;
    			if(i % prime[j] == 0) break;
    		}
    	}
    }
    
    int main()
    {
    	init();
    	int n, m;
    	
    	phifac[1] = phifac[2] = 1;
    	REP(i, 3, MAXN)
    		phifac[i] = (long long)phifac[i-1] * (is_prime[i] ? i-1 : i) % MOD;
    	
    	while(~scanf("%d%d", &n, &m) && n)
    	{
    		int ans = phifac[m];
    		REP(i, m + 1, n + 1) ans = (long long)ans * i % MOD;
    		printf("%d
    ", (ans - 1 + MOD) % MOD);
    	}
    	
    	return 0;
    }
  • 相关阅读:
    Openwave V7 不支持中文的解决方法
    VBS的疑惑,它们不考虑效率吗?
    删除顽固 NTServic和webacc.exe病毒。
    我的电脑怎么多了一些乱七八糟的东西。
    阿怒再发,突然的发现,为了编码输入速度!
    庆祝开博,也算给自己加油!
    超级简单的工厂模式温度转换
    阿怒乱弹之VS05重构的提取方法操作不方便啊!
    随笔嘛!就是随便下笔~呵呵!
    Oracle数据库一样平常维护手册2
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819493.html
Copyright © 2011-2022 走看看