• TopCoder SRM 660 Div2 Problem 1000 Powerit (积性函数)


    令$f(x) = x^{2^{k}-1}$,我们可以在$O(k)$的时间内求出$f(x)$。

    如果对$1$到$n$都跑一遍这个求解过程,时间复杂度$O(kn)$,在规定时间内无法通过。

    所以需要优化。

    显然这是一个积性函数,那么实际上只要对$10^{6}$以内的质数跑$O(k)$的求解过程。

    而$10^{6}$以内的质数不到$8*10^{4}$个,优化之后可以通过。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    typedef long long LL;
    
    const int N = 1e6 + 10;
    
    int f[N];
    int c[N];
    int ans;
    
    int Pow(int i, int k, int m){
    	int p = i, q = p;
    	rep(j, 1, k - 1){
    		q = 1ll * q * q % m;
    		p = 1ll * p * q % m;
    	}
    
    	return p;
    }
    
    int cal(int x, int k, int m){
    	if (~f[x]) return f[x];
    	else return f[x] = Pow(x, k, m);
    }
    
    class Powerit {
    	public:
    		int calc(int n, int k, int m){
    			memset(f, -1, sizeof f);
    			ans = 0;
    			rep(i, 1, 1e6){
    				for (int j = i + i; j <= 1e6; j += i) c[j] = i;
    			}
    
    			ans = cal(1, k, m);
    			rep(i, 2, n){
    				int x = c[i], y = i / c[i];
    				if (x == 1){
    					ans = ans + (f[i] = cal(i, k, m));
    					ans %= m;
    					continue;
    				}
    
    				f[i] = 1ll * cal(x, k, m) * cal(y, k, m) % m;
    				ans = ans + f[i];
    				ans %= m;
    			}
    
    			return ans;
    				
    		}
    };
    

      

  • 相关阅读:
    使用asp.net调用谷歌地图api
    JAVASCRIPT+DHTML实现表格拖动
    strcpy & memcpy区别
    python解析邮件的时候编码问题
    snprintf不能使用"字符串指针"赋值,可以使用字符数组
    二级结构体的赋值和访问方法
    C lstat major MAJOR 获得设备号
    C解析config
    C语言中的DEBUG
    opencv实例二:缩放一张图片
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8449185.html
Copyright © 2020-2023  润新知