CERC_2008_Tower(hdu 2971)

34 篇文章 0 订阅
29 篇文章 0 订阅

PRO IS HERE


由  a(n) = 2*a(2)*a(n-1) - a(n-2)

let p = 2*a(2);

==>a(n) =p*a(n-1) - a(n-2)

==>a(n)^2 = p^2*a(n-1)^2 - 2*p*a(n-1)*a(n-2) + a(n-2)^2................(1)

let s(n) =sum( a(i) );

s(n) = s(n-1) + a(n)^2   ................................................................... (2)

a(n)*a(n-1) = p*a(n-1)^2 - a(n-1)*a(n-2)...................(3)




so we have:

a(n-1)^2                        0 ,   1    ,    0    ,    0                   a(n-2)^2

a(n)^2                    =     1 ,   p^2,    -2*p,    0         *        a(n-1)^2

a(n)*a(n-1)                    0 ,   p  ,    -1    ,    0                  a(n-1)*a(n-2)

s(n-1)                            0 ,  1   ,     0    ,    1                   s(n-2)


use matrix to do this.


Problem is sovle now.

Ps: At begin I got TLE then I chang the methed but then Igot WA for amount of time becauseI used lld instand of I64d.BE remmenber to use I64d in hdu oj.



MY code :

#include<cstdio>

#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define nMax 10
#define LL long long
LL mod;

template<typename T>
struct Matrix{
	T mtix[nMax][nMax];
	int n;
	Matrix(int n=1):n(n) {
		FOR(i,0,n-1) FOR(j,0,n-1) mtix[i][j] = 0;
		FOR(i,0,n-1) mtix[i][i] = 1;
	}
	friend Matrix operator * (const Matrix& a,const Matrix& b) {
		Matrix c(a.n);
		FOR(i,0,a.n-1) FOR(j,0,a.n-1) {
			c.mtix[i][j] = 0;
			FOR(k,0,a.n-1) if(a.mtix[i][k] && b.mtix[k][j]){
			    c.mtix[i][j] += a.mtix[i][k] * b.mtix[k][j] ;
                c.mtix[i][j]%=mod;
			}
		}
		return c;
	}
	friend Matrix Exp(Matrix a,int n){
		Matrix c(a.n);
		Matrix b = a;
		while(n){
            if(n&1) c=c*b;
            n >>= 1;
            b = b*b;
		}
		return c;
	}
	void init(T p) {
		p%=mod;
		FOR(i,0,n-1) FOR(j,0,n-1) mtix[i][j] = 0 ;
		mtix[1][1] = p*p%mod;
		mtix[0][1] = mtix[1][0] = mtix[3][1] = mtix[3][3] = 1;
		mtix[1][2] = ((-2*p) % mod + mod) % mod;
		mtix[2][1] = p;
		mtix[2][2] = ((-1  ) % mod + mod) % mod;
	}
};

LL b[5];
int main(){
	//freopen("input.txt","r",stdin);
	int n;
	LL a;
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%I64d%d%I64d",&a,&n,&mod);
		a%=mod;
        if(mod == 1){
            printf("0\n");
            continue;
		}
		Matrix<LL>  s(4);
		s.init(a*2);
		b[1]=a*a%mod,b[0]=1LL,b[2]=a,b[3]=1;
		s = Exp( s ,n-1 );
		LL ans = 0LL;
		FOR(i,0,3) ans = (ans+s.mtix[3][i]*b[i]) % mod;
		printf("%I64d\n",ans);
	}

	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值