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的更多相关文章
随机推荐
- YII2 自定义日志路径
YII 提供的日志写入方法: 1.Yii::getLogger()->log($message, $level, $category = 'application') 2.Yii::trace( ...
- 黄永成-thinkphp讲解-个人博客讲解26集
如果是要导入 前后台分组都公用的 第三方类库, 就将类库(*.class.php文件) 放在 App下的Class文件夹中. 导入方法是: import('Class.Image', APP_PATH ...
- dreamwaver的动态相关文件 工具栏搜索
dreamwaver是很好的编辑工具, 用过很多ide, 对php,js, css代码来说, dw确实是很好很方便的一个工具 php本身设置了很多的 预定义常量, 函数, 可以用来获取当前运行php的 ...
- ASP跨域调用Webservices方法
仅用于记录与分享,直接贴代码: <script type="text/javascript"> function check(){ var title=$('#titl ...
- 清北暑假模拟day1 爱
/* 水题 */ #include<iostream> #include<cstdio> #include<string> #include<cstring& ...
- LYDSY模拟赛day3 序列
NOIP不考可持久,弃坑
- 湖南附中模拟day1 瞭望塔
/* 这个题要用到树的性质,一般比较难的图论题会往这方面靠拢,这样用很容易出错,应该先写暴力,然后再去一点点想正解 */ //暴力70分 #include<iostream> #inclu ...
- 【活动】不用买书,不用花钱,可以免费看HTML5入门连载了
清华大学出版社推出的<HTML 5网页开发实例详解>适合HTML 5开发初学者和前端开发工程师.本书一经上市,就获得了读者的一致好评,为感谢读者,推出本书的连载活动. 本书术新颖.与时 ...
- Java并发包源码学习之AQS框架(二)CLH lock queue和自旋锁
上一篇文章提到AQS是基于CLH lock queue,那么什么是CLH lock queue,说复杂很复杂说简单也简单, 所谓大道至简: CLH lock queue其实就是一个FIFO的队列,队列 ...
- 【C语言入门教程】5.6 函数库和文件
函数库是为代码复用建立的,将同一类型,需要在不同的程序里使用的函数放置在一起,就组成了一个函数库.如 C 语言的标准库,它集合了开发者常用的函数.开发者自行编写的函数也可以组成函数库,通常称之为自定义 ...