博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu - 3049 - Data Processing(乘法逆元)
阅读量:6078 次
发布时间:2019-06-20

本文共 1496 字,大约阅读时间需要 4 分钟。

题意:N(N<=40000)个数n1, n2, ..., nN (ni<=N),求(2 ^ n1 + 2 ^ n2 + ... + 2 ^nN) / N % 1000003。

题目链接:

——>>RJ白书上说“因为‘乘法逆’太重要了……”,上一年南京区赛同学也碰到了求逆元……如今,学习了。。

      什么是乘法逆?ab % m = 1 (这里的 a, b 分别都是模 m 的同余等价类),a 模 m 的乘法逆是 b,同一时候,b 模 m 的乘法逆是a。

      乘法逆有什么用?这个用处可还真不小。。假设要求 a / b % m(保证 b | a),可是 a 非常大非常大,比方 a = 2 ^ 40000,这个式子可不等价于 (a % m) / (b % m) % m。。这时,乘法逆就能够上场了。。一个数除以 b 后模 m,等价于该数乘以 b 模 m 的乘法逆后模 m。。于是上式可变成 a * b的乘法逆 % m,这就easy多了,就是 (a % m) * (b的乘法逆 % m) % m。。

      怎么求乘法逆?要求 a 模 m 的乘法逆,设其为 x,由于 a * x % m = 1,所以 a * x + m * y = 1。。这是什么,一元二次方程,于是乎,扩展欧几里得飞一下就出来了。。得意

#include 
typedef long long LL;const int MOD = 1000003;const int MAXN = 40000 + 10;int N, kase;LL sum;int pow2[MAXN];void GetPow2(){ pow2[0] = 1; for (int i = 1; i < MAXN; ++i) { pow2[i] = (pow2[i - 1] << 1) % MOD; }}void Read(){ int n; sum = 0; scanf("%d", &N); for (int i = 0; i < N; ++i) { scanf("%d", &n); sum = (sum + pow2[n]) % MOD; }}void gcd(LL a, LL b, LL& d, LL& x, LL& y){ if (!b) { d = a; x = 1; y = 0; return; } else { gcd(b, a % b, d, y, x); y -= a / b * x; }}LL Inv(int a, int n){ LL ret, d, y; gcd(a, n, d, ret, y); return d == 1 ? (ret + n) % n : -1;}void Solve(){ LL ret; LL inv = Inv(N, MOD); ret = sum * inv % MOD; printf("Case %d:%I64d\n", ++kase, ret);}int main(){ int T; kase = 0; GetPow2(); scanf("%d", &T); while (T--) { Read(); Solve(); } return 0;}

你可能感兴趣的文章
修改字符集
查看>>
HackTheGame 攻略 - 第四关
查看>>
js删除数组元素
查看>>
带空格文件名的处理(find xargs grep ..etc)
查看>>
华为Access、Hybrid和Trunk的区别和设置
查看>>
centos使用docker下安装mysql并配置、nginx
查看>>
关于HTML5的理解
查看>>
需要学的东西
查看>>
Internet Message Access Protocol --- IMAP协议
查看>>
Linux 获取文件夹下的所有文件
查看>>
对 Sea.js 进行配置(一) seajs.config
查看>>
第六周
查看>>
解释一下 P/NP/NP-Complete/NP-Hard 等问题
查看>>
javafx for android or ios ?
查看>>
微软职位内部推荐-Senior Software Engineer II-Sharepoint
查看>>
sql 字符串操作
查看>>
【转】Android布局优化之ViewStub
查看>>
网络安全管理技术作业-SNMP实验报告
查看>>
根据Uri获取文件的绝对路径
查看>>
Flutter 插件开发:以微信SDK为例
查看>>