HDU - 5187 zhx's contest(快速幂+快速乘法)

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

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

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

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

他想你告诉他有多少种排列是漂亮的。由于答案很大,因此只须要输出答案模p以后的值。

spa

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

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 Inputxml

2 233
3 5

Sample Outputblog

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);
                 }
           }
    }
}
相关文章
相关标签/搜索