zoukankan      html  css  js  c++  java
  • [JLOI2015]有意义的字符串

    题意

    Description

    B 君有两个好朋友,他们叫宁宁和冉冉。有一天,冉冉遇到了一个有趣的题目:输入 b;d;n,求

    [lfloor left ( frac{b+sqrt{d}}{2} ight ) ^n floor mathrm{mod} p ]

    其中(p=7528443412579576937)

    Input

    一行三个整数 b;d;n

    Output

    一行一个数表示模 7528443412579576937 之后的结果。

    Sample Output

    76

    HINT

    其中 (0<b^2 le d<(b+1)^2 le 10^{18},n le 10^{18}),并且 (b mod 2=1,d mod 4=1)

    分析

    因为这个底数长得特别像特征方程的根,所以考虑构造数列,使得

    [a_n = A*(frac{b+sqrt{d}}{2})^n + B*(frac{b-sqrt{d}}{2})^n ]

    假设特征方程是(x^2 + bx +c=0),则

    [b = -b_0 \ b^2 -4c = d_0 ]

    所以得到数列的递推公式:

    [a_n = b a_{n-1} - frac{b^2-d}{4} a_{n-2} ]

    由于我们想让(A=1,B=1),所以(a_0 = 2 ,a_1=b)

    因为(b mod 2=1,d mod 4=1),所以(frac{b^2-d}{4})必然是整数。那么(a_n)就可以用矩阵乘法解决了。那么

    [(frac{b+sqrt{d}}{2})^n = a_n - (frac{b-sqrt{d}}{2})^n ]

    因为(0<b^2 le d<(b+1)^2),所以(frac{b-sqrt{d}}{2} in (-1,0]),题目要求的是下取整,所以当(b^2<d,n mod 2 =0)时,答案要减去1。

    时间复杂度(O(2^3 log n log modulo))

    代码

    #include<bits/stdc++.h>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read(){
    	rg T data=0,w=1;
    	rg char ch=getchar();
    	while(!isdigit(ch)){
    		if(ch=='-') w=-1;
    		ch=getchar();
    	}
    	while(isdigit(ch))
    		data=data*10+ch-'0',ch=getchar();
    	return data*w;
    }
    template<class T>il T read(rg T&x){
    	return x=read<T>();
    }
    typedef unsigned long long ULL;
    
    co ULL mod=7528443412579576937;
    ULL add(ULL x,ULL y){
    	return (x+=y)>=mod?x-mod:x;
    }
    ULL mul(ULL x,ULL y){
    	ULL re=0;
    	for(;y;y>>=1,x=add(x,x))
    		if(y&1) re=add(re,x);
    	return re;
    }
    ULL A[2][2],ANS[2][2],c[2][2];
    void mul(ULL a[2][2],ULL b[2][2]){
    	for(int i=0;i<2;++i)
    		for(int j=0;j<2;++j)
    			for(int k=0;k<2;++k)
    				c[i][j]=add(c[i][j],mul(a[i][k],b[k][j]));
    	for(int i=0;i<2;++i)
    		for(int j=0;j<2;++j)
    			b[i][j]=c[i][j],c[i][j]=0;
    }
    ULL b,d,n;
    int main(){
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	read(b),read(d),read(n);
    	A[0][0]=b,A[0][1]=(d-b*b)/4,A[1][0]=1;
    	ANS[0][0]=b,ANS[1][0]=2;
    	bool del=b*b<d&&n%2==0;
    	for(;n;n>>=1,mul(A,A))
    		if(n&1) mul(A,ANS);
    	printf("%llu
    ",add(ANS[1][0],mod-del));
    	return 0;
    }
    
  • 相关阅读:
    关于java.lang.reflect.InvocationTargetException
    Java并发编程(三)后台线程(Daemon Thread)
    Lab 7-2
    Lab 7-1
    Lab 6-3
    Lab 6-2
    Lab 6-1
    Lab 5-1
    Lab 3-4
    Lab 3-3
  • 原文地址:https://www.cnblogs.com/autoint/p/10422929.html
Copyright © 2011-2022 走看看