/*
题意:给1~n,求n个数组成的排列满足先增后减或先减后增或单调递增递减的个数
思路:第i相对于前i-1个是最大的,所以前i-1个数先增后减或先减后增序列基础上第i个数都有两个位置可放置,
而单调增减只能放到第一个和最后的位置。所以是2的n次方-2种方案。
但要注意:n=1,输出1,p=1 输出0,且先要判断p
求2的n次方用到快速乘法,因为两个ll类型乘超ll范围
*/
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
#define ll long long
ll n,p;
ll mul(ll a,ll b){
ll res=0;
while(a){
if(a&1){
res=(res+b)%p;
}
b=b*2%p;
a>>=1;
}
return res;
}
ll poww(ll x,ll k){
ll res=1;
while(k){
if(k&1){
res=mul(res,x);
}
x=mul(x,x);
k>>=1;
}
return res;
}
int main()
{
while(~scanf("%I64d%I64d",&n,&p)){
if(p==1) printf("0\n");
else if(n==1) printf("1\n");
else{
ll res=poww(2,n)-2;
if(res<0) res+=p;
printf("%I64d\n",res);
}
}
return 0;
}
poj 5187(单调序列问题+快速乘)
最新推荐文章于 2020-03-28 14:32:28 发布