[数学推导]对称轴

  • 源自校内模拟赛

Statement

  • \[(\sum_{i=0}^{p-1}\binom{2i}im^i)\bmod p \]

  • \(1\le m<p\le 10^{14}\)\(p\) 为质数

  • 多组数据,数据组数不超过 \(10^4\)

Solution

  • 神仙题

  • 一个转化:

  • \[\binom{2n}n=\frac 1{(n!)^2}(\prod_{i=1}^n(2i-1))(\prod_{i=1}^n2i)=\frac{2^n}{n!}\prod_{i=1}^n(2i-1) \]

  • 这看上去没什么用

  • 但我们可 (bu) 以 (neng) 想到把 \(\prod\) 里面的每个数都取反后加上 \(p\) 再除以 \(2\)

  • \[ans=\sum_{i=0}^{p-1}\frac{(2m)^i}{i!}\prod_{j=1}^i(2j-1)=\sum_{i=0}^{p-1}\frac{(-4m)^i}{i!}\prod_{j=1}^i(\frac{p+1}2-j) \]

  • \[=\sum_{i=0}^{p-1}(-4m)^i\frac{\prod_{j=1}^i(\lfloor\frac p2\rfloor-j+1)}{i!}=\sum_{i=0}^{\lfloor\frac p2\rfloor}\binom{\lfloor\frac p2\rfloor}i(-4m)^i=(1-4m)^{\lfloor\frac p2\rfloor} \]

  • 于是快速幂套快 (gui) 速乘即可,每组数据 \(O(\log^2p)\)

  • 当然如果你有高超的打表和猜想技巧,这题是可以被打表水过去的

Code

#include <bits/stdc++.h>

template <class T>
inline void read(T &res)
{
	res = 0; bool bo = 0; char c;
	while (((c = getchar()) < '0' || c > '9') && c != '-');
	if (c == '-') bo = 1; else res = c - 48;
	while ((c = getchar()) >= '0' && c <= '9')
		res = (res << 3) + (res << 1) + (c - 48);
	if (bo) res = ~res + 1;
}

typedef long long ll;

ll rqy, m;

ll prod(ll a, ll b)
{
	ll res = 0;
	while (b)
	{
		if (b & 1) res = (res + a) % rqy;
		a = (a + a) % rqy;
		b >>= 1;
	}
	return res;
}

ll qpow(ll a, ll b)
{
	ll res = 1;
	while (b)
	{
		if (b & 1) res = prod(res, a);
		a = prod(a, a);
		b >>= 1;
	}
	return res;
}

void work()
{
	read(rqy); read(m);
	printf("%lld\n", qpow((1ll - (m << 2) + (rqy << 2)) % rqy, rqy - 1 >> 1));
}

int main()
{
	int T; read(T);
	while (T--) work();
	return 0;
}
posted @ 2019-12-11 16:56  epic01  阅读(728)  评论(0编辑  收藏  举报