ZS and The Birthday Paradox

问题:http://codeforces.com/contest/711/problem/E
概率计算问题,需结合数论知识化简运算规模
关键知识点:
1. gcd(a, b) = gcd(b - a, b or a) (if b > a)


2. x | 2^i ===>  2^n - x | 2^i (n >= i) 从而将求能整除 2^n - x的最大2次幂转换为求能整除x的最大二次幂


3. Legendre's formula 求能整除k!的最大二次幂,时间复杂度O(log k)

https://en.wikipedia.org/wiki/Legendre%27s_formula


4. 取模运算相关的性质
i) 取模对加、减、乘是封闭的
ii)若a能整除b, 则 (a / b) % p = (a % p + k * p) / (b % p), 其中 k < p - 1
证明:
记 a = b * c, 其中 b = m * p + y1, c = n * p + y2
则有
(a / b)% p = c % p = y2
另一方面
    a % p = (b * c) % p = (y1 * y2) % p, b % p = y1
由于
0 <= y1 * y2 <= (p - 1)^2 ===> y1 * y2 - a % p = k * p, 0 <= k < p - 1
要使命题成立,则需令
a % p + k * p = y1 * y2, 且 0 <= k < p - 1
iii)费马小定理 应用:简化取模计算
p为质数,则有 a^p ≡ a (mod p);若gcd(a, p) = 1, 进一步有a^(p - 1) ≡ 1 (mod p)
从而有
a^x ≡ a^(x % (p-1)) (mod p) 即将 a^x 中所有 a^(p-1) 去除


5. 在求分子项时涉及到除法运算,亦可使用费马小定理求逆元

http://blog.csdn.net/ac__y/article/details/9248023


实现:

#include 
    
    
     
     
using namespace std;

typedef long long ll;
const int MOD = int(1e6 + 3);

ll n, k;

ll powM(ll a, ll b)
{
	ll rsl = 1;
	while (b)
	{
		if (b & 1) rsl = rsl * a % MOD;
		a = a * a % MOD;
		b >>= 1;
	}
	return rsl;
}

ll sum()
{
	ll rsl, base;
	rsl = 0, base = 2;
	while (base <= k - 1)
	{
		rsl += (k - 1) / base;
		base <<= 1;
	}
	return rsl;
}

void solve()
{
	cin >> n >> k;
	if (n <= 62 && k > (1LL << n))
	{
		cout << 1 << " " << 1 << endl;
		return;
	}
	ll up, down, gcd = powM(2, sum());
	//down = powM(2, ((n % (MOD - 1)) * ((k - 1) % (MOD - 1)) - sum() % (MOD - 1)) % (MOD - 1));
	down = powM(2, (n % (MOD - 1)) * ((k - 1) % (MOD - 1)) % (MOD - 1));
	while (down % gcd)
		down += MOD;
	down /= gcd;
	if (k - 1 >= MOD)
		up = 0;
	else
	{
		ll tmp = 1, base = powM(2, n);
		for (ll i = 1; i < k; ++i)
			tmp = (tmp * (base - i)) % MOD;
		while (tmp % gcd)
			tmp += MOD;
		up = tmp / gcd;
	}
	if (down < up)
		up -= MOD;
	cout << down - up << " " << down << endl;
}

int main()
{
	solve();
	return 0;	
}
    
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值