zoukankan      html  css  js  c++  java
  • 「HDU 3292」 No more tricks, Mr Nanguo

    Description

    给定一个正整数 (n,k),求不定方程 (x^2 - n cdot y^2 = 1) 的解,其中 (x,y) 为正整数。

    由于方程解很多,所以你的解需要使 (x) 在所有解中为第 (k) 小的。

    由于这个解可能很大,所以请输出你得到的解中的 (x mod 8191) 的值。

    如果无解,输出 No answers can meet such conditions

    Hint

    (2le n le 29)

    (1le k le 10^9)

    Solution

    首先,这个方程其实有一个名字,叫做 “佩尔(Pell)方程”

    很容易判断无解的情况,即当 (sqrt{n} in ext{N}^+)(n) 为完全平方数时)是无解的。

    然后确定这个方程是有解的之后,我们先找出其最小解 ((x_1,y_1))

    怎么找?数据范围不大,暴力即可。

    之后的解,存在一个迭代公式:

    [x_i = x_{i-1} cdot x_1 + ny_{i-1} cdot y_1 ]

    [y_i = x_{i-1} cdot y_1 + y_{i-1} cdot x_1 ]

    下面给出证明。


    证明:

    (x_i^2 - ny_i^2)

    (= (x_{i-1} x_1 + ny_{i-1} y_1)^2 - n(x_{i-1} y_1 + y_{i-1} x_1)^2)

    (= (x_{i-1}^2 x_1^2 + n^2 y_{i-1}^2 y_1^2 + 2n x_{i-1} x_1 y_{i-1} y_1) - (nx_{i-1}^2 y_1^2 + ny_{i-1}^2 x_1^2 +2n x_{i-1} x_1 y_{i-1} y_1))

    (= x_{i-1}^2 (x_1^2 - ny_1^2) + ny_{i-1}^2 (ny_1^2 - x_1^2))

    (ecause (x_1,y_1)) 是方程的一组解,

    ( herefore x_1^2 - ny_1^2 = 1)

    ( herefore x_i^2 - ny_i^2 = x_{i-1}^2 (x_1^2 - ny_1^2) + ny_{i-1}^2 (ny_1^2 - x_1^2) =x_{i-1}^2 +ny_{i-1}^2)

    证毕。


    那么接下来,我们就可以由一个最小的正整数解,递推推出第 (k) 个解。

    然而本题中, (Theta(k)) 复杂度的算法是过不了的。

    但是前面的辛苦并没有白费,我们惊喜地发现,这个递推式子可以写成矩阵的形式:

    [egin{bmatrix} x_k \ y_k end{bmatrix} = egin{bmatrix} x_1 & ny_1 \ y_1 & x_1 end{bmatrix}^{k-1} imes egin{bmatrix} x_1 \ y_1 end{bmatrix} ]

    使用快速幂优化,递推复杂度直降至 (Theta(log k)) ,可以通过此题。

    Code

    /*
     * Author : _Wallace_
     * Source : https://www.cnblogs.com/-Wallace-/
     * Problem : HDU 3292 No more tricks, Mr Nanguo
     */
    #include<iostream>
    #include<cmath>
    #include<cstring>
    
    using std::cin;
    using std::cout;
    using std::endl;
    const int mod=8191;
    
    struct matrix {
    	int element[2][2];
    	int r,c;
    	inline matrix(int _r,int _c):r(_r),c(_c) {
    		memset(element,0,sizeof element);
    	}
    	inline int* operator [](const int &p) {
    		return element[p];
    	}
    };
    inline matrix unit_matrix(int s) {
    	matrix ret(s,s);
    	for(register int i=0;i<s;i++)
    		ret[i][i]=1;
    	return ret;
    }
    inline matrix operator *(matrix A,matrix B) {
    	matrix C(A.r,B.c);
    	for(register int i=0;i<A.r;i++)	
    		for(register int j=0;j<B.c;j++)
    			for(register int k=0;k<A.c;k++)
    				(C[i][j]+=A[i][k]*B[k][j]%mod)%=mod;
    	return C;
    }
    matrix fastpow(matrix a,int b) {
    	if(!b) return unit_matrix(a.r);
    	matrix t=fastpow(a,b>>1);
    	if(b&1) return t*t*a;
    	else return t*t;
    }
    
    signed main() {
    	int N,K;
    	while(cin>>N>>K) {
    		int SQRTN=floor(sqrt(N*1.0));
    		if(SQRTN*SQRTN==N) {
    			cout<<"No answers can meet such conditions"<<endl;
    			continue;
    		}
    		int y=1,x;
    		for(;;y++) {
    			x=floor(sqrt(N*y*y+1));
    			if(x*x-N*y*y==1) break;
    		}
    		matrix base(2,2);
    		base[0][0]=x;
    		base[0][1]=N*y;
    		base[1][0]=y;
    		base[1][1]=x;
    		
    		matrix sol(2,1);
    		sol[0][0]=x;
    		sol[1][0]=y;
    		
    		sol=fastpow(base,K-1)*sol;
    		cout<<sol[0][0]<<endl;
    	}
    }
    
  • 相关阅读:
    正向代理与反向代理的区别
    显式拥塞通知ECN剖析
    Save info in Hidden Field
    sessionID difference
    Windows server 2003 无法找到Cookies位置
    create Cookie
    SQL Server Session
    New class in ASP.NET
    Save info in Query string
    Crypto number
  • 原文地址:https://www.cnblogs.com/-Wallace-/p/12609493.html
Copyright © 2011-2022 走看看