题意:给出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的更多相关文章

随机推荐

  1. 使用BeanNameAutoProxyCreator实现spring的自动代理

    提到代理,我们可以使用ProxyBeanFactory,并配置proxyInterfaces,target和interceptorNames实现,但如果需要代理的bean很多,无疑会对spring配置 ...

  2. Coding上传项目步骤

    step1:在coding上面创建一个项目mybokestep2:在git 命令台中进入项目的根目录下面,使用git init创建.git文件夹和.gitigonre文件,帮组本地与远程的链接step ...

  3. vijos1741 观光公交 (贪心)

    https://www.vijos.org/p/1741 P1741观光公交 请登录后递交 标签:NOIP提高组2011[显示标签]   描述 风景迷人的小城Y市,拥有n个美丽的景点.由于慕名而来的游 ...

  4. HTTP协议详解(真的很经典)

    HTTP 是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和 扩展.目前在WWW中使用的是HTTP/1.0 ...

  5. H5移动端知识点总结

    H5移动端知识点总结 阅读目录 移动开发基本知识点 calc基本用法 box-sizing的理解及使用 理解display:box的布局 理解flex布局 Flex布局兼容知识点总结 回到顶部 移动开 ...

  6. C语言:输入输出

    C语言无I/O语句,i/o操作由函数实现 #include<stdio.h> 字符输出函数putchar: 格式:putchar(c) 参数:c为字符常量,变量或者表达式 功能:把字符c输 ...

  7. CodeForces 55D Beautiful numbers

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  8. C 语言sscanf

    C语言以sscanf逗号作为分割符 ]={}; ]={}; ]={}; sscanf(],&buf_b[],&buf_b[]); printf("************** ...

  9. mongodb university week4

    1.index Creation,background 如果在foreground运行index,会阻塞其他writer,如果background运行,会比较慢,但不会阻塞其他writer,可以并发写 ...

  10. java历史

    1.产生: 1990年初sun公司James Gosling等员工开发java语言的雏形,最初被命名为Oak,定位于家用电器的控制和通讯,随后因为市场的需求,公司放弃计划,后面由于Internet的发 ...