题目大意:
作为史上最强的刷子之一,zhx的老师让他给学弟(mei)们出
n
道题。
zhx认为第
i
道题的难度就是
i
。他想要让这些题目排列起来很漂亮。
zhx认为一个漂亮的序列
{ai}
下列两个条件均需满足。
1:
a1..ai
是单调递减或者单调递增的。
2:
ai..an
是单调递减或者单调递增的。
他想你告诉他有多少种排列是漂亮的。
因为答案很大,所以只需要输出答案模
p
之后的值。
解题思路:
如果
n=1
,答案是
1
,否则答案是
2n−2
。
证明:
ai
肯定是最小的或者最大的。考虑另外的数,如果它们的位置定了的话,那么整个序列是唯一的。
那么
ai
是最小或者最大分别有
2n−1
种情况,而整个序列单调增或者单调减的情况被算了2次,所以要减2。
要注意的一点是因为
p>231
,所以要用快速乘法。用法与快速幂相同。如果直接乘会超过long long范围,从而wa掉。
#include <iostream>
using namespace std;
typedef long long LL;
LL n, p;
LL mul(LL A, LL B) {
LL ans = 0;
while (B) {
if (B & 1)
ans = (ans + A) % p;
A = (A + A) % p;
B >>= 1;
}
return ans;
}
LL Pow(LL A, LL B) {
LL ans = 1;
while (B) {
if (B & 1)
ans = mul(ans, A);
A = mul(A, A);
B >>= 1;
}
return ans;
}
int main() {
while (cin >> n >> p) {
if (n == 1)
cout << 1 % p << endl;
else
cout << (Pow(2, n) + p - 2) % p << endl;
}
return 0;
}