[关闭]
@ysner 2018-08-05T17:11:41.000000Z 字数 1662 阅读 1718

[luogu_U15118]萨塔尼亚的期末考试

矩阵乘法


题面

次询问,求出

指斐波那契数列数列)

解析

的范围显然要我们矩阵快速幂。
然而这式子需要转化:(别问我最后一步怎么证)



用矩阵快速幂求个斐波那契数列都会吧。
复杂度

然后花了n小时发现由于特判,我矩阵的表示在数列中位置的量被提前更新了
所以特判要写在最前面。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<vector>
  8. #define re register
  9. #define il inline
  10. #define ll long long
  11. #define max(a,b) ((a)>(b)?(a):(b))
  12. #define min(a,b) ((a)<(b)?(a):(b))
  13. #define fp(i,a,b) for(re int i=a;i<=b;i++)
  14. #define fq(i,a,b) for(re int i=a;i>=b;i--)
  15. using namespace std;
  16. const int mod=998244353,N=2e6+100;
  17. int n,las,ans[N],tar;
  18. struct que{int n,id;bool operator < (const que &o) {return (n<o.n)||(n==o.n&&id<o.id);}}a[N];
  19. il ll gi()
  20. {
  21. re ll x=0,t=1;
  22. re char ch=getchar();
  23. while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  24. if(ch=='-') t=-1,ch=getchar();
  25. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  26. return x*t;
  27. }
  28. struct Matrix
  29. {
  30. int a[4][4];
  31. il Matrix(){memset(a,0,sizeof(a));}
  32. Matrix operator *(Matrix b)
  33. {
  34. Matrix c;
  35. fp(i,1,2)
  36. fp(j,1,2)
  37. fp(k,1,2)
  38. (c.a[i][j]+=1ll*a[i][k]*b.a[k][j]%mod)%=mod;
  39. return c;
  40. }
  41. }S,T;
  42. il int ksm(re int G,re int o)
  43. {
  44. re int P=G;G=1;
  45. while(o)
  46. {
  47. if(o&1) G=1ll*G*P%mod;
  48. P=1ll*P*P%mod;
  49. o>>=1;
  50. }
  51. return G;
  52. }
  53. int main()
  54. {
  55. S.a[1][1]=1;S.a[1][2]=1;
  56. re int q=gi();
  57. fp(i,1,q) a[i].n=gi(),a[i].id=i;
  58. sort(a+1,a+1+q);tar=2;
  59. fp(i,1,q)
  60. {
  61. n=a[i].n;
  62. if(n==1||n==2) {ans[a[i].id]=1;continue;}
  63. las=tar;tar=n+3;
  64. memset(T.a,0,sizeof(T.a));T.a[1][1]=T.a[1][2]=T.a[2][1]=1;
  65. re int k=tar-las;
  66. while(k)
  67. {
  68. if(k&1) S=S*T;
  69. T=T*T;
  70. k>>=1;
  71. }
  72. ans[a[i].id]=2*ksm(1ll*n*(n+1)%mod,mod-2)%mod*((1ll*n*S.a[1][2]%mod-S.a[1][1]+2+mod)%mod)%mod;
  73. }
  74. fp(i,1,q) printf("%d\n",ans[i]);
  75. return 0;
  76. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注