• Project Euler 48 Self powers( 大数求余 )



    题意:

    项的自幂级数求和为 11 + 22 + 33 + … + 1010 = 10405071317。

    求如下一千项的自幂级数求和的最后10位数字:11 + 22 + 33 + … + 10001000

    思路:

    1. 求最后十位数字 % 1010 即可。

    2. 对于快速幂中数据溢出的问题,有两种解决方法:

      1. 方法一:对于两个数 x y,现在想求 x * y % MOD,可以将 x 表示成 a * DIGS + b,y 表示成 c * DIGS + d,x * y % MOD 则等价与 ( a * c * DIGS2 + a * d * DIGS + b * c * DIGS + b * d ) % MOD ( DIGS = 1E5 ) 这样进行分解后就可以有效的避免数据溢出。
      2. 方法二:对于快速幂中的乘法,我们可以写个与快速幂类似的快速乘法,在快速乘法的过程中不断取模来保持数据在范围之内。

    3. 对于 i % 10 == 0 的情况 i i % MOD 一定为 0


    方法一代码:

    /*************************************************************************
        > File Name: euler048t2.c
        > Author:    WArobot 
        > Blog:      http://www.cnblogs.com/WArobot/ 
        > Created Time: 2017年07月01日 星期六 16时41分22秒
     ************************************************************************/
    
    #include <stdio.h>
    #include <inttypes.h>
    
    #define MOD 10000000000
    #define MAX_N 1000
    #define DIGS 100000
    
    int64_t Multi(int64_t x , int64_t y) {
    	int64_t a , b , c , d , ans = 0;
    	a = x / DIGS;	b = x % DIGS;
    	c = y / DIGS;	d = y % DIGS;
    	ans = (ans + ((a * d) % MOD * DIGS) % MOD) % MOD;
    	ans = (ans + ((b * c) % MOD * DIGS) % MOD) % MOD;
    	ans = (ans +  (b * d) % MOD) % MOD;
    	return ans;
    }
    int64_t quick_pow(int64_t a , int64_t b , int64_t mod) {
    	int64_t ret = 1;
    	while (b) {
    		if (b & 1)	ret = Multi(ret , a);
    		a = Multi(a , a);
    		b >>= 1;
    	}
    	return ret;
    }
    int32_t main() {
    	int64_t sum = 0;
    	for (int32_t i = 1 ; i <= MAX_N ; i++) {
    		if (i % 10 == 0)	continue;
    		sum = (sum + quick_pow(i , i , MOD)) % MOD;
    	}
    	printf("%"PRId64"
    ",sum);
    	return 0;
    }
    

    方法二代码:

    /*************************************************************************
        > File Name: euler048.c
        > Author:    WArobot 
        > Blog:      http://www.cnblogs.com/WArobot/ 
        > Created Time: 2017年07月01日 星期六 16时21分58秒
     ************************************************************************/
    
    #include <stdio.h>
    #include <inttypes.h>
    
    #define MAX_N 1000
    #define MOD 10000000000
    
    int64_t quick_multi(int64_t a , int64_t b , int64_t mod) {
    	int64_t ret = 0;
    	while (b) {
    		if (b & 1)	ret = (ret + a) % mod;
    		a = (a << 1) % mod;
    		b >>= 1;
    	}
    	return ret % mod;
    }
    int64_t quick_power(int64_t a , int64_t b , int64_t mod) {
    	int64_t ret = 1;
    	while (b) {
    		if (b & 1) ret = quick_multi(ret , a , mod);
    		a = quick_multi(a , a , mod);
    		b >>= 1;
    	}
    	return ret % mod;
    }
    int32_t main() {
    	int64_t sum = 0;
    	for (int32_t i = 1 ; i <= MAX_N ;i++) {
    		if (i % 10 == 0)	continue;
    		sum = (sum + (quick_power((int64_t)i , (int64_t)i , MOD))) % MOD;
    	}
    	printf("%"PRId64"
    ",sum);
    	return 0;
    }
  • 相关阅读:
    oracle 函数WMSYS.WM_CONCAT()的用法(行转列) 老猫
    PL/SQL 数独 九宫图 老猫
    oracle10g rman backup and recover 老猫
    Oracle SQL的优化 老猫
    Oracle数据库中的字符处理技巧总结 老猫
    WITH分析函数 老猫
    30套JSP网站源代码合集
    Java获取系统信息(cpu,内存,硬盘,进程等)的相关方法
    [原]Web Service学习
    常用Web Service汇总(天气预报、时刻表等)
  • 原文地址:https://www.cnblogs.com/WArobot/p/7102831.html
Copyright © 2020-2023  润新知