作为史上最强的刷子之一,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; }