题目链接
2 233 3 5
2 1HintIn the first case, both sequence {1, 2} and {2, 1} are legal. In the second case, sequence {1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1} are legal, so the answer is 6 mod 5 = 1
题意:题目链接
题解:
如果 n=1 ,答案是 1 ,否则答案是 2n−2 。
证明: ai 肯定是最小的或者最大的。考虑另外的数,如果它们的位置定了的话,那么整个序列是唯一的。
那么 ai 是最小或者最大分别有 2n−1 种情况,而整个序列单调增或者单调减的情况被算了2次,所以要减2。
要注意的一点是因为 p>231 ,所以要用快速乘法。用法与快速幂相同。如果直接乘会超过long long范围,从而wa掉。
代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<string> #include<queue> #include<stack> #include<map> #include<set> #include<stdlib.h> #include<vector> #define inff 0x3fffffff #define nn 1100 #define mod 1000000007 typedef __int64 LL; typedef unsigned __int64 LLU; const LL inf64=inff*(LL)inff; using namespace std; LL n,p; LL qiu(LL x,LL y) { LL tem=x; LL re=0; while(y) { if(y%2) { re=(re+tem)%p; } y/=2; tem=(tem+tem)%p; } return re; } LL po(LL x,LL y) { LL tem=x; LL re=1; while(y) { if(y%2) { re=qiu(re,tem); } tem=qiu(tem,tem); y/=2; } return re; } int main() { while(scanf("%I64d%I64d",&n,&p)!=EOF) { if(p==1) puts("0"); else if(n==1) { puts("1"); } else { printf("%I64d\n",((po(2,n)-2)%p+p)%p); } } return 0; }