题意:有n个问题要解决,n-m个问题被改变,增强了剩下m个问题到最简单的a个问题的数据,现在这个人可以解决那a个最简单的没有改变的问题,有k次机会获得代码段,所有需要的代码段长度为l,每次获得代码段的机会给x,y,z三个数字,代表不能获得x行代码的概率为y/z(保证xi求和=l)
求这个人能解决多少道题(结果要mod4933)
思路:
给的变量很多,有用的就k,a,y,z;(当时就是因为不懂那么多变量,还有那个分数取模,唉)
这个人能解决的题目数量就是a+(1-y1/z1)*(1-y2/z2)...*(1-yk/zk);
因为后面的是一个概率,涉及一个知识:
对于a/b这个分数取p模=a*对1/b取p模
对对1/b取p模=逆元x,其中bx=1(mod p)
由费马小定理b^(p-1)=1(mod p) 当b和p互质
(费马小定理还要用到快速幂)
所以x=b^(p-2)(mod p)
因此只需要求出每一个分数的逆元x相乘再加上a,最后mod p输出就行
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Mod = 4933;
int quick_pow(int base)
{
int ans = 1;
int y = Mod - 2;
while (y)
{
if (y & 1)
{
ans =(ans*base)%Mod;
}
base = (base * base) % Mod;
y >>= 1;
}
return ans % Mod;
}
int main()
{
int m, n, k, a, l;
cin >> n >> m >> k >> a >> l;
int ans = 1;
while (k--)
{
int x, y, z;
cin >> x >> y >> z;
//p/q(mod m)等价于p*x(x是1/q的逆元)
if (x)//x还可能为0呢,这个坑。。啧
{
ans = ans * (z - y) % Mod * quick_pow(z) % Mod;
}
//i/z的逆元=z^(p-2)Mod(p),费马小定理
}
cout << (ans + a) % Mod;
return 0;
}