求助 HNOI
查看原帖
求助 HNOI
425646
DreamsChaser楼主2021/9/19 22:59
#include <bits/stdc++.h>
#define reg register

#define for_u(i, a, b) for (reg int i = a; i <= b; ++ i)
#define for_d(i, a, b) for (reg int i = a; i >= b; -- i)
#define for_r(x) for (reg int i = head[x]; i; i = nxt[i])

#define Aestas 362699
#define president 19260817
#define int long long

using namespace std;

typedef long long LL;
typedef long double LDB;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

const int N = 2000010;

LL a[N], b[N], mod, Pow2[N], Pow5[N];

void exgcd(reg LL a, reg LL b, reg LL &x, reg LL &y)
{
	if (!b) {x = 1; y = 0; return;}
	exgcd(b, a % b, y, x);
	y -= (a / b) * x;
}

inline LL inv(reg LL n, reg LL p) {LL x, y; exgcd(n, p, x, y); return (x + p) % p;}

inline LL qpow(reg LL a, reg LL b, reg LL p)
{
	reg LL res = 1;
	for (; b; b >>= 1) {if (b & 1) res = res * a % p; a = a * a % p;}
	return res;
}

inline LL CRT()
{
	reg LL x, y, ans = 0;
	exgcd(b[2], b[1], x, y); ans = x * b[2] % mod * a[1] % mod;
	exgcd(b[1], b[2], x, y); ans = (ans + x * b[1] % mod * a[2] % mod) % mod;
	return ans;
}

LL calc(reg LL n, reg LL q, reg LL qk)
{
	if (!n) return 1;
	if (n >= qk) return 0;
	reg LL xh = qpow(((q == 2) ? Pow2[qk] : Pow5[qk]), n / qk, qk);
	xh = xh * ((q == 2) ? Pow2[n % qk] : Pow5[n % qk]) % qk;
	return xh * calc(n / q, q, qk) % qk;
}

inline LL exLucas(reg LL n, reg LL m)
{
	reg LL tot = 0; for (reg LL i = n; i; i /= 2) tot += i / 2; for (reg LL i = m; i; i /= 2) tot -= i / 2; for (reg LL i = n - m; i; i /= 2) tot -= i / 2;
	a[1] = qpow(2, tot, b[1]) * calc(n, 2, b[1]) % b[1] * inv(calc(m, 2, b[1]), b[1]) % b[1] * inv(calc(n - m, 2, b[1]), b[1]) % b[1];
	tot = 0; for (reg LL i = n; i; i /= 5) tot += i / 5; for (reg LL i = m; i; i /= 5) tot -= i / 5; for (reg LL i = n - m; i; i /= 5) tot -= i / 5;
	a[2] = qpow(5, tot, b[2]) * calc(n, 5, b[2]) % b[2] * inv(calc(m, 5, b[2]), b[2]) % b[2] * inv(calc(n - m, 5, b[2]), b[2]) % b[2];
    return (CRT() + mod) % mod;	
}

signed main()
{
	mod = 2000000000ll; b[1] = 512ll; b[2] = 1953125ll;
	Pow2[1] = 1; for_u (i, 2, b[1]) Pow2[i] = Pow2[i - 1] * ((i % 2) ? i : 1) % b[1];
	Pow5[1] = 1; for_u (i, 2, b[2]) Pow5[i] = Pow5[i - 1] * ((i % 5) ? i : 1) % b[2];
	
	reg int A, B, k;
	while (~scanf("%lld %lld %lld", &A, &B, &k))
	{
		reg int ans = qpow(2, A + B, mod);
		if (A == B) ans -= exLucas(2 * A, A);
		else if (A != B + 1) for_u (i, 1, A - B - 1) ans = (ans + exLucas(A + B, B + i)) % mod;
		ans = (ans + mod) % mod; ans /= 2;
		reg int nmod = 1; for_u (i, 1, k) nmod *= 10;
        printf("%0*lld\n", k, ans % nmod);
	}
	return 0;
}

经过测试,exLucas 在 n, m 较小的时候是对的(大数据我也不知道对不对),然后公式应该没有问题。我怀疑是在取模上出现了失误。

求助。

2021/9/19 22:59
加载中...