快速乘法-快速幂

Description
从 n 个不同元素中任取 m(m≤n)个元素,按照一定的顺序排列起来,叫做从 n
个不同元素中取出 m 个元素的一个排列。当 m=n 时所有的排列情况叫全排列。
你觉得 xxy 会问你全排列的个数吗?Xxy:这个问题能淹死你,我才不问呢。我
要问的是求 n 的全排列中,先递增后递
减、先递减后递增的全排列的个数。由于答案可能很大,对 p 取余
Input
输入包含多组测试数据每组测试
数据一行两个整数 n,p
Output
对于每组测试数据输出一行表示答案
3 5

4
2 233

0
Hint
设数据组数为 T
对于 10%的数据,n<=10,p<=1000,T=1
对于另外 10%的数据,n<=12,p<=1000,T<=12
对于另外 10%的数据,n<=100,p<=100000,T<=100
对于另外 10%的数据,n<=100000,p<=1000000,T=1
对于另外 10%的数据,n<=100000,p<=1000000,T<=1000
对于另外 20%的数据,n<=1e9,p<=1e9,T<=1000
对于 100%的数据,n<=1e18,p<=1e18,T<=1000

 

找规律 

对于3 我们可以找出所有情况 

1 3 2

2 3 1

2 1 3

3 1 2

我们可以发现 4的所有递增递减的情况一定是基于3的所有情况 

 1 3 2   我们可以将4放在 3前面 1 4 3 2 或者 放在3后面 1 3 4 2 

其他情况相同 n全排列的单峰情况 一定可以由n-1的单峰排列情况推出 

共2的n次方种

但这不是全部  

还有特殊情况 1 2 3  -->1 2 4 3

          -->4 1 2 3   

       3 2 1  -->3 4 2 1

          -->3 2 1 4   

共 2n+4种

2n用快速幂和快速乘即可

 

 1 #include <cstdio>
 2 #include <cctype>
 3 #include <algorithm>
 4 
 5 typedef long long LL;
 6 
 7 using namespace std;
 8 
 9 int T;
10 
11 LL n,p;
12 
13 inline void read(LL&x) {
14     int f=1;register char c=getchar();
15     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
16     for(;isdigit(c);x=x*10+c-48,c=getchar());
17     x=x*f;
18 }
19 
20 inline LL quick_plus(LL b,LL k) {
21     LL ans=0;
22     while(k) {
23         if(k&1) ans=(ans+b)%p;
24         k>>=1;
25         b=(b+b)%p;
26     }
27     return ans%p;
28 }
29 
30 inline LL quick_pow(LL a,LL k) {
31     LL ans=1;
32     while(k) {
33         if(k&1) ans=quick_plus(ans,a);
34         k>>=1;
35         a=quick_plus(a,a);
36     }
37     return ans;
38 }
39 
40 int hh() {
41 //    freopen("permutation.in","r",stdin);
42 //    freopen("permutation.out","w",stdout);
43     while(~scanf("%lld%lld",&n,&p)) {
44         if(n==1||n==2) {
45             printf("0\n");
46             continue;
47         }
48         LL ans=quick_pow(2,n);
49         LL L=4-p;
50         ans=(ans-L+p)%p;
51         printf("%lld\n",ans);
52     }
53     return 0;
54 }
55 
56 int sb=hh();
57 int main(int argc,char**argv) {;}
代码

 

posted @ 2017-09-13 15:03  拿叉插猹哈  阅读(286)  评论(0编辑  收藏  举报