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的更多相关文章
随机推荐
- Python开发【第三篇】:Python基本数据类型
运算符 1.算数运算: 2.比较运算: 3.赋值运算: 4.逻辑运算: 5.成员运算: 基本数据类型 1.数字 int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31- ...
- ActionScript学习笔记
ActionScript学习笔记 ActionScript中预定义的数据类型:Boolean.int.Number.String.uint 其中,int.Number.uint是处理数字的.int用来 ...
- 获取指定版本号svn
代码需求获取 svn update svnworkpath --username xxx --password xxx -r r464 r464 为指定版本号 可以获取指定版本号的代码 也 也可以在 ...
- Junit初级编码(一)第一个Junit测试程序
序,Junit测试是单元测试的一个框架,提供了很多方法,供我们快速开展单元测试.目前最新版本JAR包为4.12,官网地址为http://junit.org/ 一.第一个Junit测试程序 1 去官网下 ...
- Access应用日志<一>
今天在确认实习生不能帮忙搭建数据库后,自己根据业务需求尝试搭了一个小型access数据库. 主要目的:储存历史月度数据,避免每次从公司数据库下载数据的麻烦,节省数据拉取时间. 搭建了以acct id为 ...
- 【bzoj2243】[SDOI2011]染色
题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如"11 ...
- hdu.1010.Tempter of the Bone(dfs+奇偶剪枝)
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- 大数据之tachyon(未完版)
1.内存文件存储系统 Tachyon是一个开源分布式存储系统,拥有高性能.高容错等优点.并具有类Java的文件API.插件式的底层文件系统.兼容Hadoop MapReduce和 Apache Spa ...
- expdp / impdp 用法详解
一 关于expdp和impdp 使用EXPDP和IMPDP时应该注意的事项:EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用.EXPDP和IMPDP是服务端的工具程 ...
- windows和linux文件共享
###Samba安装 [root@samba ~]# yum install -y samba* [root@samba ~]# rpm -qa | grep samba ###开启s ...