作为史上最强的刷子之一,zhx的老师让他给学弟(mei)们出n道题。zhx认为第i道题的难度就是i。他想要让这些题目排列起来很漂亮。

zhx认为一个漂亮的序列{ai}下列两个条件均需满足。

1:a1..ai是单调递减或者单调递增的。

2:ai..an是单调递减或者单调递增的。

他想你告诉他有多少种排列是漂亮的。因为答案很大,所以只需要输出答案模p之后的值。

Input Multiply test cases(less than 10001000). Seek EOF as the end of the file. 

Output For each case, there are two integers nn and pp separated by a space in a line. (1n,p10181≤n,p≤1018)OutputFor each test case, output a single line indicating the answer. 
Sample Input

2 233
3 5

Sample Output

2
1
Hint
In 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

思路:最终推导式2^n-2
因为乘数可能超long,所以用到了快速乘法
代码:
import java.util.Scanner;
public class Main {
      public static long multi(long a,long b,long p){//快速乘法
            long ans=0;
            while(b>0){
                  if((b&1)==1) ans=(ans+a)%p;
                  a=(a+a)%p;
                  b>>=1;
            }
            return ans;
      }
      public static long quick_pow(long a,long b,long p){//快速幂
            long ans=1;
            while(b>0){
                  if((b&1)==1) ans=multi(ans,a,p)%p;
                  a=multi(a,a,p)%p;
                  b>>=1;
            }
            return ans;
      }
      public static void main(String[] args) {
           Scanner scan=new Scanner(System.in);
           while(scan.hasNext()){
                 long n=scan.nextLong();
                 long p=scan.nextLong();
                 if(p==1) System.out.println("0");//情况特判
                 else if(n==1) System.out.println("1");
                 else{
                     long ans=quick_pow(2,n,p)-2;
                     if(ans<0)  ans+=p;//注意ans为负数情况,因为快速幂计算取余-2可能小于0
                     System.out.println(ans);
                 }
           }
    }
}
posted on 2020-01-14 19:45  qdu_lkc  阅读(207)  评论(0编辑  收藏  举报