【BestCoder#8】【1002】【Reading comprehension】【题解】【数列推通项】

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4990

题意:

数列a_n={2a_{n-1}  if n%2==0

             {2a_{n-1}+1 if n%2==1  

            a_0=0

求an%m


考虑合并相邻两个操作,即构造数列b_n=a_2n

则 bn=4b_{n-1}+2

=>bn+2/3=4(b_{n-1}+2/3)

=>令cn=bn+2/3

=>cn=8/3*4^(n-1)

则ans=(8*4^(n-1)-2)/3   (以上的n为原来的n整除2)

若原来的n为奇数则ans=2*ans+1


式子推完,然后发现3和m可能不互质……逆元没法算……

yy一下?……失败

度娘一下?……失败

请教神犇?……失败

最后就没过……

看了别人代码发现不互质时暴力扩大模数范围求逆元直接除就好了……

当然是数小的时候,数大了现在还不会……

标算是矩乘233

Code:

#include <cstdio>
#include<iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<vector>
using namespace std;
typedef long long LL;
LL n,m;
LL power(LL x,LL k,LL MOD){
	LL ans=1;
	for(;k;k>>=1){
		if(k&1)ans=(ans*x)%MOD;
		x=(x*x)%MOD;
	}return ans%MOD;
}
void exgcd(LL a,LL b,LL &x,LL &y){
	if(!b){
		x=1;y=0;
	}else{
		exgcd(b,a%b,x,y);
		LL t=x;
		x=y;
		y=t-a/b*y;
	}
}
LL inv(LL a,LL MOD){
	LL x,y;
	exgcd(a,MOD,x,y);
	while(x<0)x+=MOD;
	return x%MOD;
}
int main(){
	while(cin>>n>>m){
		LL cn,bn;
		if(n==1){
			cout<<1%m<<endl;continue;
		}
		cn=power(4,n/2-1,m*3)*8%(3*m);
		bn=cn-2;
		while(bn<0)bn+=(m*3);
		bn/=3;
		if(n&1)bn=(2*bn+1)%(3*m);
		cout<<bn%m<<endl;
	}
	return 0;
}


你可能感兴趣的:(HDU)