zju3547
题意:给出n(1<=n<=10^8),求小于n的,求所有与n互质的数字的四次幂的加和是多少。
分析:容斥原理
首先要知道四次幂求和公式,1^4+2^4+...+n^4=n*(n+1)*(2n+1)*(3n^2+3n-1)/30
先求所有小于等于n的数字的四次幂和,然后减去那些不互质的即可。
这个减去的过程用到了容斥原理。
先对n分解质因子,每个不同的质因子只保留一个。
然后分别枚举这些质因子的组合情况,由奇数个因子组成的数要减去,由偶数个因子组成的数要加上。
对于一个因子组合的乘积a,我们需要一次性计算a^4+(2a)^4 + (3a)^4+...
将其转化为a^4 * (1^4+2^4+...)即可。
这道题还有一个难点,就是公式中有除法(除以30),却还要进行模运算。
除法是不支持模运算的,因此我们要将除法转化为乘法,除以30变为乘以30的逆元。
逆元的意思是,如果a、b互为mod c下的逆元,则a * b = 1 (mod c)。
求逆元可以用扩展欧几里德gcd(30,MOD,x,y),把x/gcd(30,MOD)整理到0~MOD-1范围内即为30的逆元。
具体原因查阅扩展欧几里德算法。
- #include <cstdio>
- using namespace std;
- #define D(x)
- const int MOD = (int)(1e9) + ;
- const int MAX_FACTOR = ;
- int n;
- int factor_num;
- long long factor[MAX_FACTOR];
- long long inverse;
- //n(n+1)(2n+1)(3n^2+3n-1)/30
- long long to_forth(long long value)
- {
- long long ret = value;
- ret = ret * ret % MOD;
- ret = ret * ret % MOD;
- return ret;
- }
- long long cal(long long value)
- {
- long long num = n / value;
- long long ret = ;
- ret = ret * num % MOD * (num + ) % MOD;
- ret = ret * ( * num + ) % MOD;
- ret = ret * ((num * num % MOD * % MOD + * num % MOD - ) % MOD) % MOD;
- if (ret / != ret * inverse % MOD)
- {
- D(printf("#%lld %lld\n", ret / , ret * inverse % MOD));
- }else
- {
- D(printf("**\n"));
- }
- ret = ret * inverse % MOD;
- ret = ret * to_forth(value) % MOD;
- return ret;
- }
- void get_factors()
- {
- factor_num = ;
- int m = n;
- for (int i = ; i * i <= m; i++)
- {
- if (m % i == )
- factor[factor_num++] = i;
- while (m % i == )
- {
- m /= i;
- }
- }
- if (m != )
- {
- factor[factor_num++] = m;
- }
- }
- long long work()
- {
- long long ans = ;
- for (int i = ; i < ( << factor_num); i++)
- {
- int num = ;
- long long temp = ;
- int index = ;
- for (int mask = ; mask <= i; mask <<= , index++)
- {
- if ((mask & i) == )
- {
- continue;
- }
- num++;
- temp *= factor[index];
- }
- D(printf("temp=%lld\n", temp));
- if (num & )
- ans += cal(temp);
- else
- ans -= cal(temp);
- ans = (ans % MOD + MOD) % MOD;
- }
- ans = ((cal() - ans) % MOD + MOD) % MOD;
- return ans;
- }
- void gcd_extend(long long a,long long b,long long &g,long long &x,long long &y)
- {
- if (!b)
- {
- g = a;
- x = ;
- y = ;
- return;
- }
- gcd_extend(b, a % b, g, y, x);
- y -= a / b * x;
- }
- int main()
- {
- long long x, y, g;
- gcd_extend(, MOD, g, x, y);
- D(printf("%lld %lld %lld\n", x, y, g));
- x = (x % MOD + MOD) % MOD;
- inverse = x / g;
- D(printf("%lld\n", inverse));
- D(printf("%lld\n", inverse * % MOD));
- int t;
- scanf("%d", &t);
- while (t--)
- {
- scanf("%d", &n);
- if (n == )
- {
- puts("");
- continue;
- }
- get_factors();
- int ans_int = work();
- printf("%d\n", ans_int);
- }
- return ;
- }
zju3547的更多相关文章
随机推荐
- JDK自带方法实现AES对称加密
请看代码. 1 package jdbc.pro.lin; 2 3 import java.security.InvalidAlgorithmParameterException; 4 import ...
- MySQL里的found_row()与row_count()的解释及用法
MySQL中有两个函数来计算上一条语句影响了多少行,不同于SqlServer/Oracle,不要因为此方面的差异而引起功能问题 出处:mysqlpub.com MySQL中有两个函数来计算上一条语 ...
- Unity相关路径
Application.dataPath 只读 在项目根目录下读取文件,但移动端没有访问权限.一般适用于PC端调试用. Application.streamingAssetsPath 在Assets目 ...
- [整理]AngularJS学习资源
https://angular.io/docs/js/latest/(2.0官方网站) http://www.linuxidc.com/Linux/2014-05/102139.htm(Angular ...
- 深入理解Javascript面向对象编程
深入理解Javascript面向对象编程 阅读目录 一:理解构造函数原型(prototype)机制 二:理解原型域链的概念 三:理解原型继承机制 四:理解使用类继承(继承的更好的方案) 五:建议使用封 ...
- WCF binding的那些事!!!
原文地址:http://www.cnblogs.com/Anima0My/archive/2008/04/16/1156146.html WCF中常用的binding方式: BasicHttpBind ...
- Tomcat 6 —— Realm域管理
本篇来源于官方文档,但不仅仅是翻译,其中不乏网上搜索的资料与自己的理解. 如有错误,请予指正. 什么是Realm 首先说一下什么是Realm,可以把它理解成“域”,也可以理解成“组”,因为它类似 类U ...
- 系列文章:老项目的#iPhone6与iPhone6Plus适配#(持续更新中,更新日期2014年10月12日 星期日 )
本文永久地址为http://www.cnblogs.com/ChenYilong/p/4020399.html ,转载请注明出处. ********************************** ...
- rem和em,px的使用
rem是CSS3中新增加的一个单位值,他和em单位一样,都是一个相对单位.不同的是em是相对于元素的父元素的font-size进行计算:rem是相对于根元素html的font-size进行计算.这样一 ...
- CentOS 6.5 zabbix 3.0.4 监控MySQL性能
安装mysql [root@test3 /]# yum -y install mysql mysql-server 初始化数据库 [root@test3 /]# /etc/init.d/mysqld ...