bzoj 2142 礼物
2016-09-16 21:21
197 查看
转载声明:http://blog.csdn.net/wzq_QwQ/article/details/46709471
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2142
题意:中文题意没人看不懂的,,,
个人感想:链接上说得太清楚了,我倒是感觉好神奇这样的做法 对非素数取模就有一种可以个解决的办法了,这是一个很好的题目..这是参照了别人的文章的 ..因为有些理论的东西我也不知道为什么可以这样.就顺着文章写了,, 不过有点不习惯用他写的中国剩余定理…
分析:数论
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2142
题意:中文题意没人看不懂的,,,
个人感想:链接上说得太清楚了,我倒是感觉好神奇这样的做法 对非素数取模就有一种可以个解决的办法了,这是一个很好的题目..这是参照了别人的文章的 ..因为有些理论的东西我也不知道为什么可以这样.就顺着文章写了,, 不过有点不习惯用他写的中国剩余定理…
分析:数论
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * */ #include <iostream> using namespace std; #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <sstream> #include <cctype> #include <vector> #include <set> #include <cstdlib> #include <map> #include <queue> //#include<initializer_list> //#include <windows.h> //#include <fstream> //#include <conio.h> #define MaxN 0x7fffffff #define MinN -0x7fffffff #define lson 2*k #define rson 2*k+1 typedef long long ll; const int INF=0x3f3f3f3f; const int maxn=1e5+10; int Scan()//读入整数外挂. { int res = 0, ch, flag = 0; if((ch = getchar()) == '-') //判断正负 flag = 1; else if(ch >= '0' && ch <= '9') //得到完整的数 res = ch - '0'; while((ch = getchar()) >= '0' && ch <= '9' ) res = res * 10 + ch - '0'; return flag ? -res : res; } void Out(int a) //输出外挂 { if(a>9) Out(a/10); putchar(a%10+'0'); } ll P,n,m; ll w[maxn]; ll a[maxn]; int top; ll fac[maxn]; ll pri[maxn]; typedef pair<ll,ll> pa; ll qmod(ll a,ll b,ll p) { ll res=1; while(b) { if(b&1) {res=(res*a)%p;} a=(a*a)%p; b>>=1; } return res; } void exgcd(ll a,ll b,ll &x,ll &y) { if(!b) { x=1,y=0;; return ; } exgcd(b,a%b,y,x); y=y-a/b*x; } ll inv(ll a,ll b) { ll x,y,gcd; exgcd(a,b,x,y); return (x%b+b)%b; } void getfac(ll p) { bool flag; for(int i=2;i*i<=p;i++) { flag=false; if(p%i==0) { flag=true; fac[top]=1; pri[top]=i; } while((p%i)==0) { p/=i; fac[top]*=i; } if(flag)top++; } if(p>1) {fac[top]=pri[top]=p;top++;} } pa fact(ll k,ll n) { if(n==0)return pa(0,1); int x=n/pri[k],y=n/fac[k]; ll ans=1; if(y) { for(int i=2;i<fac[k];i++) { if(i%pri[k]!=0)ans=(ans*1ll*i)%fac[k]; } ans=qmod(ans,y,fac[k]); } for(int i=y*fac[k]+1;i<=n;i++) { if(i%pri[k]!=0)ans=ans*1ll*i%fac[k]; } pa tmp=fact(k,x); return pa(x+tmp.first,ans*tmp.second%fac[k]); } ll calc(int k,ll n,ll m) { if(n<m)return 0; pa a=fact(k,n),b=fact(k,m),c=fact(k,n-m); return qmod(pri[k],a.first-b.first-c.first,fac[k])*a.second%fac[k]*inv(b.second,fac[k])%fac[k]*inv(c.second,fac[k])%fac[k]; } ll china() { ll gcd,y,x=0; for(int i=0;i<top;i++) { ll r=P/fac[i]; exgcd(fac[i],r,gcd,y); x=(x+r*y*a[i])%P; } return (x+P)%P; } ll work(ll n,ll m) { for(int i=0;i<top;i++)a[i]=calc(i,n,m); return china(); } int main() { #ifndef ONLINE_JUDGE freopen("coco.txt","r",stdin); freopen("lala.txt","w",stdout); #endif scanf("%lld%lld%lld",&P,&n,&m); top=0; ll sum=0; for(int i=0;i<m;i++) { scanf("%lld",&w[i]); sum+=w[i]; } if(n<sum) {printf("Impossible\n");return 0;} getfac(P); ll ans=work(n,sum)%P; //cout<<ans<<endl; for(int i=0;i<m;i++) { ans=(ans*work(sum,w[i]))%P; sum-=w[i]; } printf("%lld\n",ans); return 0; }
相关文章推荐
- Linux调度时机
- 对类内静态变量的分析
- HttpClient学习笔记
- 两个数互换
- [置顶] 【NuGet】NuGet发布原创源程序
- 素数 筛选获取
- Android应用闪屏页延迟跳转的三种写法
- 接口
- 用R做中文文本分析--载入需要的数据包及载入时可能遇到的问题
- 使用opencv_haartraining.exe做样本训练死循环无法生成.xml文件的解决办法--convert_cascade.exe
- 去除已排序数组中的重复元素
- 继承和多态
- HDOJ 2016 数据的交换输出
- LeetCode 88. Merge Sorted Array
- oracle数据库函数
- 串行与并行
- light oj 1311 - Unlucky Bird (物理啊)
- 困难重重的新版本发布之路
- 单例模式的两种线程安全并且效率的写法
- linux如何查看所有的用户和组信息?