您的位置:首页 > 其它

poj 5187(单调序列问题+快速乘)

2015-04-19 12:01 127 查看
/*
题意:给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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: