【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 }
View Code

4002: [JLOI2015]有意义的字符串

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 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。

Source

[Submit][Status][Discuss]
posted @ 2015-04-21 22:56  Tunix  阅读(1619)  评论(4编辑  收藏  举报