HDU 4990(找规律+构造矩阵快速幂)

Read the program below carefully then answer the question. 
#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include <cstdio> 
#include<iostream> 
#include <cstring> 
#include <cmath> 
#include <algorithm> 
#include<vector> 

const int MAX=100000*2; 
const int INF=1e9; 

int main() 

  int n,m,ans,i; 
  while(scanf("%d%d",&n,&m)!=EOF) 
  { 
    ans=0; 
    for(i=1;i<=n;i++) 
    { 
      if(i&1)ans=(ans*2+1)%m; 
      else ans=ans*2%m; 
    } 
    printf("%d\n",ans); 
  } 
  return 0; 
}

Input

Multi test cases,each line will contain two integers n and m. Process to end of file. 
[Technical Specification] 
1<=n, m <= 1000000000

Output

For each case,output an integer,represents the output of above program.

Sample Input

1 10
3 100

Sample Output

1
5

思路:

 

代码:

 一开始错了好几次,用long才对,所以以后都用long完事


import java.util.Arrays;
import java.util.Scanner;

public class main10 {
	 static long n,m;
	 static int max=3;
	 public static long[][] multi(long a[][],long b[][]){
		long res[][]=new long [max][max];
		 for(int i=0;i<max;i++)
			 Arrays.fill(res[i], 0);
		 for(int i=0;i<max;i++)
			 for(int j=0;j<max;j++)
				 for(int k=0;k<max;k++)
					 res[i][j]=(res[i][j]+a[i][k]*b[k][j]%m)%m;
		 return res;
	 }
	 public static  long[][] quick_pow( long a[][]){
		 long res[][]=new  long[max][max];
		 for(int i=0;i<max;i++)
			 for(int j=0;j<max;j++)
				 if(i==j) res[i][j]=1;
				 else res[i][j]=0;
		 long b=n-2;
		 while(b!=0){
			 if((b&1)==1) res=multi(res,a);
			 b>>=1;
			 a=multi(a,a);
		 }
		 return res;
	 }
     public static void main(String[] args) {
		 Scanner scan=new Scanner(System.in);
		 while(scan.hasNext()){
			 n=scan.nextInt();
			 m=scan.nextInt();
			 if(n==1){
				 System.out.println(1%m);
				 continue;
			 }
			 else if(n==2){
				System.out.println(2%m);
				continue;
			 }
			 else{
			 long a[][]=new long[max][max];
			 for(int i=0;i<max;i++)
				 Arrays.fill(a[i], 0);
			 a[0][0]=a[0][2]=a[1][0]=a[2][2]=1;
			 a[0][1]=2;
			 long b[][]=new  long[max][max];
			 b=quick_pow(a);
			 long c[][]=new  long[max][max];
			 for(int i=0;i<max;i++)
				 Arrays.fill(c[i], 0);  
			 c[0][0]=2; c[1][0]=1; c[2][0]=1;
			 c=multi(b,c);
			 System.out.println(c[0][0]);
			 }
		 }
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ksuper&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值