【问题描述】
作为史上最强的刷子之一,zhx的老师让他给学弟(mei)们出n道题。zhx认为第i道题的难度就是i。他想要让这些题目排列起来很漂亮。
zhx认为一个漂亮的序列{ai}下列两个条件均需满足。
1:a1..ai是单调递减或者单调递增的。
2:ai..an是单调递减或者单调递增的。
他想你告诉他有多少种排列是漂亮的。因为答案很大,所以只需要输出答案模p之后的值。
【题解】
对于整段序列单调增或减,就2种情况。
对于先增后减或先减后增:确定一个序列中的最小值(最大值),其他的要么在左边,要么在右边,有2^(n-1)*2种
而在这2^n种情况中重复计算了单调增或减得情况2次。
所以答案就是2^n-2
由于数据范围很大,不能直接快速幂,需要用到快速乘。
1 /************* 2 HDU 5187 3 by chty 4 2016.11.1 5 *************/ 6 #include<iostream> 7 #include<cstdio> 8 #include<cstdlib> 9 #include<cstring> 10 #include<ctime> 11 #include<cmath> 12 #include<algorithm> 13 using namespace std; 14 typedef long long ll; 15 ll n,mod; 16 ll mul(ll x,ll y) {return ((x*y-(ll)(((long double)x*y+0.5)/mod)*mod)%mod+mod)%mod;}//一行快速乘 17 ll fast(ll a,ll b){ll ans=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ans=mul(ans,a);return ans;}//一行快速幂 18 int main() 19 { 20 while(~scanf("%lld%lld",&n,&mod)) 21 { 22 if(n==1) printf("%lld ",n%mod); 23 else printf("%lld ",(fast(2,n)+mod-2)%mod); 24 } 25 return 0; 26 }