HDU 5446 Unknown Treasure(lucas定理+中国剩余定理)——2015 ACM/ICPC Asia Regional Changchun Online
2016-08-28 13:26
357 查看
此文章可以使用目录功能哟↑(点击上方[+])
Accept: 0 Submit: 0
Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
On the way to the next secret treasure hiding place, the mathematician discovered a cave unknown to the map. The mathematician entered the cave because it is there. Somewhere deep in the cave, she found a treasure chest with a combination
lock and some numbers on it. After quite a research, the mathematician found out that the correct combination to the lock would be obtained by calculating how many ways are there to pick m different apples among n of them and modulo it with M. M is the product
of several different primes.
On the first line there is an integer T(T≤20) representing the number of test cases.
Each test case starts with three integers n,m,k(1≤m≤n≤10^18,1≤k≤10) on a line where k is the number of primes. Following on the next line are k different primes p1,...,pk. It is guaranteed that M=p1⋅p2⋅⋅⋅pk≤10^18 and pi≤10^5 for every i∈{1,...,k}.
For each test case output the correct combination on a line.
1
9 5 2
3 5
6
解题思路:
【题意】
求解
,M为k个不同质数的乘积
【类型】
lucas定理+中国剩余定理
【分析】
由于M为k个不同质数的乘积
所以M不一定为质数,这就导致我们无法直接使用lucas定理来求解组合数取模
那我们该怎么办呢?
先来回顾一下中国剩余定理
我们知道,对于一元模线性方程组
它的解可以写成x=a+kb(k≥0)的形式,并且
再回过头来看这道题,
在lucas定理不能直接使用的情况下,我们是否能够缩小
,使得模运算可以直接计算呢?
答案显然是可以的
我们可以通过中国剩余定理,将
缩小为等价的一元模线性方程组的最小解,这样就可以直接取模了
所以题目到此就转化为了求一元模线性方程组的最小解,即a
那么等价的一元模线性方程组是多少呢?如下:
于是乎,此题到此结束
【时间复杂度&&优化】
题目链接→HDU 5446 Unknown Treasure
/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define eps 1e-9
#define LL long long
#define PI acos(-1.0)
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 15;
const int M = 100005;
const int inf = 1000000007;
const int mod = 7;
__int64 quick_mod(__int64 a,__int64 b,__int64 p)
{
__int64 ans=1;
a%=p;
while(b)
{
if(b&1)
{
ans=ans*a%p;
b--;
}
b>>=1;
a=a*a%p;
}
return ans;
}
__int64 C(__int64 n,__int64 m,__int64 p)
{
if(m>n) return 0;
__int64 ans=1;
for(int i=1;i<=m;i++)
{
__int64 a=(n+i-m)%p;
__int64 b=i%p;
ans=ans*(a*quick_mod(b,p-2,p)%p)%p;
}
return ans;
}
__int64 Lucas(__int64 n,__int64 m,__int64 p)
{
if(m==0) return 1;
return C(n%p,m%p,p)*Lucas(n/p,m/p,p)%p;
}
int group;
LL n
,a
;
LL Egcd(LL a,LL b,LL &x,LL &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
LL d,tp;
d=Egcd(b,a%b,x,y);
tp=x;
x=y;
y=tp-a/b*y;
return d;
}
LL solve()
{
int i;
bool flag = false;
LL n1 = n[0], n2, b1 = a[0], b2, bb, d, t, k, x, y;
for (i = 1; i < group; i++)
{
n2 = n[i], b2 = a[i];
bb = b2 - b1;
d = Egcd (n1, n2, x, y);
if (bb % d) //模线性解k1时发现无解
{
flag = true;
break;
}
k = bb / d * x; //相当于求上面所说的k1【模线性方程】
t = n2 / d;
if (t < 0) t = -t;
k = (k % t + t) % t; //相当于求上面的K`
b1 = b1 + n1*k;
n1 = n1 / d * n2;
}
if(flag)
return -1; //无解
/******************求正整数解******************/
if(b1==0) //如果解为0,而题目要正整数解,显然不行
b1=n1; //n1刚好为所有ni的最小公倍数,就是解了
/******************求正整数解******************/
return b1; //形成的解:b1, b1+n1, b1+2n1,..., b1+xni...
}
int main()
{
int i,t;
__int64 p,q,M;
scanf("%d",&t);
while(t--)
{
M=1;
scanf("%I64d%I64d%d",&p,&q,&group);
for(i=0;i<group;i++)
{
scanf("%I64d",&n[i]);
M*=n[i];
a[i]=Lucas(p,q,n[i]);
}
printf ("%I64d\n",solve()%M);
}
return 0;
}
菜鸟成长记
HDU 5446 Unknown Treasure
Accept: 0 Submit: 0Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Problem Description
On the way to the next secret treasure hiding place, the mathematician discovered a cave unknown to the map. The mathematician entered the cave because it is there. Somewhere deep in the cave, she found a treasure chest with a combinationlock and some numbers on it. After quite a research, the mathematician found out that the correct combination to the lock would be obtained by calculating how many ways are there to pick m different apples among n of them and modulo it with M. M is the product
of several different primes.
Input
On the first line there is an integer T(T≤20) representing the number of test cases.Each test case starts with three integers n,m,k(1≤m≤n≤10^18,1≤k≤10) on a line where k is the number of primes. Following on the next line are k different primes p1,...,pk. It is guaranteed that M=p1⋅p2⋅⋅⋅pk≤10^18 and pi≤10^5 for every i∈{1,...,k}.
Output
For each test case output the correct combination on a line.
Sample Input
19 5 2
3 5
Sample Output
6
Problem Idea
解题思路:【题意】
求解
,M为k个不同质数的乘积
【类型】
lucas定理+中国剩余定理
【分析】
由于M为k个不同质数的乘积
所以M不一定为质数,这就导致我们无法直接使用lucas定理来求解组合数取模
那我们该怎么办呢?
先来回顾一下中国剩余定理
我们知道,对于一元模线性方程组
它的解可以写成x=a+kb(k≥0)的形式,并且
再回过头来看这道题,
在lucas定理不能直接使用的情况下,我们是否能够缩小
,使得模运算可以直接计算呢?
答案显然是可以的
我们可以通过中国剩余定理,将
缩小为等价的一元模线性方程组的最小解,这样就可以直接取模了
所以题目到此就转化为了求一元模线性方程组的最小解,即a
那么等价的一元模线性方程组是多少呢?如下:
于是乎,此题到此结束
【时间复杂度&&优化】
题目链接→HDU 5446 Unknown Treasure
Source Code
/*Sherlock and Watson and Adler*/#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define eps 1e-9
#define LL long long
#define PI acos(-1.0)
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 15;
const int M = 100005;
const int inf = 1000000007;
const int mod = 7;
__int64 quick_mod(__int64 a,__int64 b,__int64 p)
{
__int64 ans=1;
a%=p;
while(b)
{
if(b&1)
{
ans=ans*a%p;
b--;
}
b>>=1;
a=a*a%p;
}
return ans;
}
__int64 C(__int64 n,__int64 m,__int64 p)
{
if(m>n) return 0;
__int64 ans=1;
for(int i=1;i<=m;i++)
{
__int64 a=(n+i-m)%p;
__int64 b=i%p;
ans=ans*(a*quick_mod(b,p-2,p)%p)%p;
}
return ans;
}
__int64 Lucas(__int64 n,__int64 m,__int64 p)
{
if(m==0) return 1;
return C(n%p,m%p,p)*Lucas(n/p,m/p,p)%p;
}
int group;
LL n
,a
;
LL Egcd(LL a,LL b,LL &x,LL &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
LL d,tp;
d=Egcd(b,a%b,x,y);
tp=x;
x=y;
y=tp-a/b*y;
return d;
}
LL solve()
{
int i;
bool flag = false;
LL n1 = n[0], n2, b1 = a[0], b2, bb, d, t, k, x, y;
for (i = 1; i < group; i++)
{
n2 = n[i], b2 = a[i];
bb = b2 - b1;
d = Egcd (n1, n2, x, y);
if (bb % d) //模线性解k1时发现无解
{
flag = true;
break;
}
k = bb / d * x; //相当于求上面所说的k1【模线性方程】
t = n2 / d;
if (t < 0) t = -t;
k = (k % t + t) % t; //相当于求上面的K`
b1 = b1 + n1*k;
n1 = n1 / d * n2;
}
if(flag)
return -1; //无解
/******************求正整数解******************/
if(b1==0) //如果解为0,而题目要正整数解,显然不行
b1=n1; //n1刚好为所有ni的最小公倍数,就是解了
/******************求正整数解******************/
return b1; //形成的解:b1, b1+n1, b1+2n1,..., b1+xni...
}
int main()
{
int i,t;
__int64 p,q,M;
scanf("%d",&t);
while(t--)
{
M=1;
scanf("%I64d%I64d%d",&p,&q,&group);
for(i=0;i<group;i++)
{
scanf("%I64d",&n[i]);
M*=n[i];
a[i]=Lucas(p,q,n[i]);
}
printf ("%I64d\n",solve()%M);
}
return 0;
}
菜鸟成长记
相关文章推荐
- HDU 5446 Unknown Treasure(中国剩余定理+卢卡斯定理)——2015 ACM/ICPC Asia Regional Changchun Online
- hdu 5444 Elven Postman 2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5443 The Water Problem(水题 找区间最大值)——2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5443 The Water Problem 2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5437.Alisha’s Party【2015 ACM/ICPC Asia Regional Changchun Online】【优先队列】9月14
- 2015 ACM/ICPC Asia Regional Changchun Online(hdu 5437 - hdu 5449)
- HDU 5437 Alisha’s Party (Priority_queue)2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5437 Alisha’s Party(优先队列+模拟)——2015 ACM/ICPC Asia Regional Changchun Online
- hdu 5443 The Water Problem 2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5441 Travel(2015 ACM/ICPC Asia Regional Changchun Online)
- hdu 5443 The Water Problem 水题 2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5438 Ponds(dfs)——2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5441.Travel【2015 ACM/ICPC Asia Regional Changchun Online】【并查集】9月18
- HDU 5441 Travel(离线 + 带权并查集)——2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5444.Elven Postman【2015 ACM/ICPC Asia Regional Changchun Online】【二叉树建立与遍历】9月14
- Hdu 5445 Food Problem (2015长春网络赛 ACM/ICPC Asia Regional Changchun Online)
- hdu 5437 Alisha's Party 2015 ACM/ICPC Asia Regional Changchun Online
- 2015 ACM/ICPC Asia Regional Changchun Online 1007 hdu 5443 线段树区间最值
- HDU 5444 Elven Postman (2015 ACM/ICPC Asia Regional Changchun Online)
- HDU 5438.Ponds【2015 ACM/ICPC Asia Regional Changchun Online】【DFS】9月13