hdu 5976 Detachment(乘法逆元)(附测试用例)
来源:互联网 发布:韩顺平java全套视频 编辑:程序博客网 时间:2024/05/18 01:23
总结来说,一个数取过模之后,他只能用逆元,不能再向以前一样.
这题的做法本身很简单,分解成2~k,就是最大.
主要就是记录下乘法逆元这个事情.
假如(a/b)%m = c
那么如果a或b是很大的,那么他们不能被直接计算出,所以要取余,那么,对a和b取余之后,(a%mb)/b就不等于c了,因为a和b都取过余了.
那么要对a,b取余时怎么办呢,就用这个叫乘法逆元的东西,(a*k)%m = c,k是b对m的乘法逆元.`
/* xzppp */#include <iostream>#include <vector>#include <cstdio>#include <string.h>#include <algorithm>#include <queue>#include <map>#include <math.h>#include <string>using namespace std;#define FFF freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define MP make_pair#define PB push_backtypedef long long LL;typedef unsigned long long ULL;const int MAXN = 100000+17;const int MAXM = 20;const int INF = 0x7fffffff;const int MOD = 1e9+7;LL add[MAXN],mul[MAXN];LL egcd(LL a, LL b, LL& x, LL& y){ LL d = a; if(b != 0){ d = egcd(b, a % b, y, x); y -= (a / b) * x; }else { x = 1; y = 0; } return d;}LL inv(LL a, LL m){ LL x, y; egcd(a, m, x, y); return (m + x % m) % m;}int main(){ #ifndef ONLINE_JUDGE FFF #endif add[1] = 0; mul[1] = 1; for (int i = 2; i < MAXN; ++i) { add[i] = i+add[i-1]; mul[i] = (mul[i-1]*i)%MOD; } int t; cin>>t; while(t--) { int n; scanf("%d",&n); if(n==1) { printf("1\n"); continue; } int l = -1,r = MAXN; while(r-l>1) { int mid = (r+l)>>1; if(add[mid]<=n) l = mid; else r = mid; } int sub = n - add[l]; LL ans = -1; if(sub>=l-1) ans = (1LL*(mul[l]*inv(2,MOD))%MOD*(l+sub-(l-2)))%MOD; else if(sub!=0) ans = (1LL*mul[l+1])*inv(l-sub+1,MOD)%MOD; else ans = mul[l]; printf("%lld\n",ans); } return 0;}
测试代码
#define FFF freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define LL long longconst int maxn = 1e5;const LL mod = 107;LL add[maxn], mul[maxn];void exgcd(LL a, LL b, LL& d, LL& x, LL& y){ //扩展欧几里得 if(!b){ d = a; x = 1; y = 0;} else{ exgcd(b, a%b, d, y, x); y -= x*(a/b); }}LL inv(LL a, LL n){ //求逆元 LL d, x, y; exgcd(a, n, d, x, y); return (x+n)%n;}void init(){ memset(add, 0, sizeof(add)); memset(mul, 0, sizeof(mul)); add[0] = add[1] = 1; add[2] = 2; mul[0] = mul[1] = 1; mul[2] = 2; for(LL i = 3; i < maxn; i++){ add[i] = add[i-1]+i; mul[i] = (mul[i-1]*i)%mod; }}int main(){ #ifndef ONLINE_JUDGE FFF #endif cout<<"in"<<endl; init(); cout<<mul[20]<<" "<<mul[10]<<endl; LL a = 1,b=1; for (int i = 2; i <= 15; ++i) { a*=i; } for (int i = 2; i <= 10; ++i) { b*=i; } b = 2; cout<<a<<" "<<b<<endl; cout<<a/b<<" "<<(a/b)%mod<<endl; cout<<(a*inv(b,mod))%mod<<endl; cout<<(double)mul[15]/mul[10]<<endl; cout<<mul[15]*inv(mul[10],mod)%mod<<endl; cout<<(mul[15]%(mod*mul[10]))/mul[10]<<endl; cout<<(a%(b*mod))/b<<endl; return 0;}
阅读全文
0 0
- hdu 5976 Detachment(乘法逆元)(附测试用例)
- HDU 5976 Detachment 逆元
- hdu 5976 Detachment 逆元+二分+数学
- HDU 5976 Detachment (逆元)
- HDU 5976 Detachment (数学规律+逆元)
- HDU 5976 Detachment(逆元)+逆元总结
- HDU 5976 Detachment(逆元+二分优化+数学分析)
- ☆HDU 5976 Detachment 详细题解(贪心+逆元+前缀和,积)
- hdu 5976 Detachment(逆元+贪心+数论+前缀和+二分 待整理)
- HDU 5976 Detachment
- HDU 5976 Detachment
- HDU 5976 Detachment
- hdu 5976 Detachment
- HDU 5976 Detachment
- HDU 5976 Detachment
- HDU 1576 乘法逆元
- 【数论】【逆元】【贪心】HDU5976 Detachment
- hdu 5976 Detachment(数论,一个结论)
- 滴滴出行2018内推编程题
- Sublime Text 3 import Anaconda 无法正常补全模块名解决办法
- 面试题 31:连续子数组的最大和(滴滴的“连续最大和”)
- Logistics Rrgression(Logistics回归)
- JAVA 反射机制(Java Reflection)总结(二)
- hdu 5976 Detachment(乘法逆元)(附测试用例)
- 关于The user specified as a definer ('root'@'%') does not exist 解决方法
- block与inline 元素
- hdu 1124 圆桌会议
- MFC中有三种文件操作的类 CFile ,CArchive,CDocument
- 【Angular2】插值表达式如何嵌套显示
- 基础算法(二分,去重,排列)
- 后台管理布局之模板继承2 补充 继承拼接
- Arctic Network POJ