【BZOJ】【4002】【JLOI2015】有意义的字符串
构造线性递推式+矩阵乘法
题解戳PoPoQQQ
为了自己以后看的方便手打一遍好了>_>
求$( \frac{b+\sqrt{d}}{2} )^n$的整数部分对p取模后的值
其中$b\mod 2=1,d\mod 4=1,b^2 \leq d<(b+1)^2,n\leq10^{18}$
思路:
构造数列$a_n=b*a_{n-1}+\frac{d-b^2}{4}*a_{n-2}$
其中$a_0=2,a_1=b$
然后我们求出这个数列的通项公式,得到$a_n=(\frac{b+\sqrt{d}}{2})^n+(\frac{b-\sqrt{d}}{2})^n$
因此得到$(\frac{b+\sqrt{d}}{2})^n=a_n-(\frac{b-\sqrt{d}}{2})^n$
由于$b \mod 2=1, d \mod 4=1$,因此$\frac{d-b^2}{4}$一定是个正整数,故我们可以利用矩阵乘法来求出这个数列的第$n$项
然后对于$80\%$的数据$b^2\leq d <(b+1)^2$,对于$20\%$的数据$b=1,d=5$,因此$(\frac{b-\sqrt{d}}{2})^n \in (-1,0]$
故后面那一项对答案有贡献当且仅当 $d\not=b^2$且$n$为偶数
时间复杂度$O(log_2n)$
P.S.话说题目给的提示:题目名有意义的字符串“jxamfe”以及那个奇怪的模数我还是没明白提示在哪了……>_>我讨厌猜字谜QAQ
1 /************************************************************** 2 Problem: 4002 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:48 ms 7 Memory:1272 kb 8 ****************************************************************/ 9 10 //Huce #5 A 11 #include<cmath> 12 #include<vector> 13 #include<cstdio> 14 #include<cstdlib> 15 #include<cstring> 16 #include<iostream> 17 #include<algorithm> 18 #define rep(i,n) for(int i=0;i<n;++i) 19 #define F(i,j,n) for(int i=j;i<=n;++i) 20 #define D(i,j,n) for(int i=j;i>=n;--i) 21 using namespace std; 22 typedef unsigned long long LL; 23 LL getll(){ 24 LL v=0,sign=1; char ch=getchar(); 25 while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();} 26 while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();} 27 return v*sign; 28 } 29 const int N=100010,INF=~0u>>2; 30 const LL MOD=7528443412579576937LL; 31 /*******************tamplate********************/ 32 LL b,d,n; 33 struct matrix{ 34 LL d[3][3]; 35 LL* operator [] (int x){ return d[x];} 36 matrix(int x=0){ 37 F(i,0,2) F(j,0,2) 38 if (i==j && i) d[i][j]=x; 39 else d[i][j]=0; 40 } 41 }a; 42 inline LL mul(LL a,LL b){ 43 LL r=0; 44 for(;b;b>>=1,a=(a+a)%MOD) 45 if (b&1) r=(r+a)%MOD; 46 return r; 47 } 48 inline matrix operator * (matrix a,matrix b){ 49 matrix c; 50 F(i,1,2) F(j,1,2) F(k,1,2) (c[i][j]+=mul(a[i][k],b[k][j]))%=MOD; 51 return c; 52 } 53 inline matrix Pow(matrix a,LL b){ 54 matrix r(1); 55 for(;b;b>>=1,a=a*a) if (b&1) r=r*a; 56 return r; 57 } 58 int main(){ 59 b=getll(); d=getll(); n=getll(); 60 a[1][1]=0; a[1][2]=(d-b*b)/4; 61 a[2][1]=1; a[2][2]=b; 62 a=Pow(a,n); 63 cout<<((a[1][1]*2%MOD+mul(b,a[2][1])-(d!=b*b&&!(n&1)))%MOD+MOD)%MOD<<endl; 64 return 0; 65 }
4002: [JLOI2015]有意义的字符串
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 54 Solved: 28
[Submit][Status][Discuss]
Description
B 君有两个好朋友,他们叫宁宁和冉冉。
有一天,冉冉遇到了一个有趣的题目:输入 b;d;n,求((b+sqrt(D)/2)^N的整数部分,请输出结果 Mod 7528443412579576937 之后的结果吧。
Input
一行三个整数 b;d;n
Output
一行一个数表示模 7528443412579576937 之后的结果。
Sample Input
1 5 9
Sample Output
76
HINT
0 <b^2 < d< (b +1)2 < 10^18。