当前位置:   article > 正文

P5343 【XR-1】分块 矩阵快速幂_nfnfnf

nfnfnf

题目描述

有一个长度为 nnn 的序列,xht37 现在想分块维护它。

PinkRabbit 要求他只准将序列分成 PRPRPR 种长度的块。

NaCly_Fish 要求他只准将序列分成 NFNFNF 种长度的块。

同一个人可能会要求 xht37 多次相同的块长。

xht37 想同时满足 PinkRabbit 和 NaCly_Fish 要求,只好使用两个人都允许的长度分块。

xht37 想知道,有多少种不同的分块方案,答案对 109+710 ^ 9 + 710​9​​+7 取模。

输入格式

第一行一个正整数 nnn,表示序列的长度。

第二行一个正整数 PRPRPR,表示 PinkRabbit 要求的分块长度的种类数。

第三行 PRPRPR 个正整数,表示 PinkRabbit 要求的 PRPRPR 种分块长度。

第四行一个正整数 NFNFNF,表示 NaCly_Fish 要求的分块长度的种类数。

第五行 NFNFNF 个正整数,表示 NaCly_Fish 要求的 NFNFNF 种分块长度。

输出格式

输出一行一个整数,表示不同分块方案的种类数对 109+710 ^ 9 + 710​9​​+7 取模的值。

样例

输入 111

  1. 4
  2. 3
  3. 1 2 3
  4. 3
  5. 1 2 4

输出 111

5

样例 111 说明

PinkRabbit 和 NaCly_Fish 都允许的块长为 {1,2}\{1,2\}{1,2}。

长度为 444 的序列分块,每块长度为 {1,2}\{1,2\}{1,2} 的方案有:

  • 1 1 1 11\ 1\ 1\ 11 1 1 1
  • 1 1 21\ 1\ 21 1 2
  • 1 2 11\ 2\ 11 2 1
  • 2 1 12\ 1\ 12 1 1
  • 2 22\ 22 2

共 555 种。

输入 222

  1. 19260817
  2. 7
  3. 8 9 6 3 7 2 1
  4. 7
  5. 4 5 2 9 7 8 3

输出 222

859254329

数据范围与提示

设最大块长为 xxx。

对于 60%60 \%60% 的数据,1≤n≤1061 \le n \le 10 ^ 61≤n≤10​6​​,1≤PR,NF,x≤101 \le PR,NF,x \le 101≤PR,NF,x≤10,保证同一个人不会要求多次相同的块长。

对于 100%100 \%100% 的数据,1≤n≤10181 \le n \le 10 ^ {18}1≤n≤10​18​​,1≤PR,NF,x≤1001 \le PR,NF,x \le 1001≤PR,NF,x≤100。

矩阵快速幂

不是

保证同一个人不会要求多次相同的块长吗  WA了好多发

f5=f(5-2) +f(5-3)

矩阵快速幂构造矩阵方法   第一行就是  0  1 1 0 0

                                                              1  0  0  0 0

                                                              0   1 0  0  0

                                                   .            .... .........

                                                              0    0   0  0 1

洛谷               760ms  

xht37的OJ     1093ms卡常-----

  1. #pragma GCC optimize("Ofast")
  2. #pragma GCC optimize("unroll-loops")
  3. #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  4. #include<cstdio>
  5. #include<cstring>
  6. #include<algorithm>
  7. using namespace std;
  8. typedef long long ll;
  9. ll mod=1e9+7;
  10. ll flag[105];
  11. ll num[105];
  12. ll exi[105];
  13. ll ma=100;
  14. ll p[105][105];
  15. ll tp2[105][105];
  16. ll ans[105];
  17. ll tp[105];
  18. void f1()
  19. {
  20. for(ll i=1; i<=ma; i++)
  21. {
  22. tp[i]=0;
  23. for(ll j=1; j<=ma; j++)
  24. {
  25. tp[i]=(tp[i]+p[i][j]*ans[j])%mod;
  26. }
  27. }
  28. for(ll i=1; i<=ma; i++)
  29. ans[i]=tp[i];
  30. }
  31. void f2()
  32. {
  33. for(ll i=1; i<=ma; i++)
  34. {
  35. for(ll j=1; j<=ma; j++)
  36. {
  37. tp2[i][j]=0;
  38. for(ll k=1; k<=ma; k++)
  39. {
  40. tp2[i][j]=(tp2[i][j]+p[i][k]*p[k][j])%mod;
  41. }
  42. }
  43. }
  44. for(ll i=1; i<=ma; i++)
  45. {
  46. for(ll j=1; j<=ma; j++)
  47. {
  48. p[i][j]=tp2[i][j];
  49. }
  50. }
  51. }
  52. void print()
  53. {
  54. for(ll i=1; i<=ma; i++)
  55. {
  56. for(ll j=1; j<=ma; j++)
  57. {
  58. printf("%lld ",p[i][j]);
  59. }
  60. printf("\n");
  61. }
  62. printf("\n");
  63. for(ll i=1;i<=ma;i++)
  64. printf("%lld ",ans[i]);
  65. printf("\n");
  66. printf("\n");
  67. }
  68. ll flag2[105];
  69. int main()
  70. {
  71. ll n;
  72. ll cnt=0;
  73. scanf("%lld",&n);
  74. memset(p,0,sizeof(p));
  75. memset(flag,0,sizeof(flag));
  76. memset(flag2,0,sizeof(flag2));
  77. memset(num,0,sizeof(num));
  78. ll l1,l2,x;
  79. scanf("%lld",&l1);
  80. for(ll i=0; i<l1; i++)
  81. {
  82. scanf("%lld",&x);flag[x]=1;
  83. }
  84. scanf("%lld",&l2);
  85. for(ll i=0; i<l2; i++)
  86. {
  87. scanf("%lld",&x);
  88. flag2[x]=1;
  89. }
  90. for(ll i=0; i<105; i++)
  91. if(flag[i]&&flag2[i])
  92. num[cnt]=i,cnt++;
  93. for(ll i=0; i<cnt; i++)
  94. p[1][num[i]]=1;
  95. for(ll i=2; i<=ma; i++)
  96. {
  97. p[i][i-1]=1;
  98. }
  99. memset(ans,0,sizeof(ans));
  100. ans[1]=1;
  101. while(n)
  102. {
  103. if(n&1)
  104. f1();
  105. //print();
  106. f2();
  107. n>>=1;
  108. }
  109. printf("%lld\n",ans[1]%mod);
  110. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/941877
推荐阅读
相关标签
  

闽ICP备14008679号