2019-ACM-ICPC-沈阳区网络赛-K. Guanguan's Happy water-高斯消元+矩阵快速幂


【Problem Description】

已知前\(2k\)个\(f(i)\),且\(f(n)=f(n-1)\cdot p(1)+f(n-2)\cdot p(2)+\dots+f(n-k)\cdot p(k)\)。求\(f(1)+f(2)+\dots+f(n)\)。

【Solution】

根据题目条件可知

\[f(k+1)=f(k)\cdot p(1)+f(k-2)\cdot p(2)+\dots+f(1)\cdot p(1)\\
f(k+2)=f(k+1)\cdot p(1)+f(k-1)\cdot p(2)+\dots+f(2)\cdot p(1)\\
\vdots\\
f(2k)=f(2k-1)\cdot p(1)+f(2k-2)\cdot p(2)+\dots+f(k)\cdot p(1)\\
\]

\(k\)个方程,\(k\)个未知数,所以可以用高斯消元求得矩阵\(P\)。则:

\[\left(\begin{matrix}
f(n)\\
f(n-1)\\
f(n-2)\\
\vdots\\
f(n-k+1)
\end{matrix}\right)=\left(\begin{matrix}
p(1)&p(2)&\dots&p(k-1)&p(k)\\
1&0&\dots&0&0\\
0&1&\dots&0&0\\
\vdots\\
0&0&\dots&1&0
\end{matrix}\right)\cdot \left(\begin{matrix}
f(n-1)\\
f(n-2)\\
f(n-3)\\
\vdots\\
f(n-k)
\end{matrix}\right)
\]

则有\(f(n)\)的前缀和\(sum(n)\):

\[\left(\begin{matrix}
f(n)\\
f(n-1)\\
f(n-2)\\
\vdots\\
f(n-k+1)\\
sum(n)
\end{matrix}\right)=\left(\begin{matrix}
p(1)&p(2)&\dots&p(k-1)&p(k)&0\\
1&0&\dots&0&0&0\\
0&1&\dots&0&0&0\\
\vdots\\
0&0&\dots&1&0&0\\
p(1)&p(2)&\dots&p(k-1)&p(k)&1
\end{matrix}\right)\cdot \left(\begin{matrix}
f(n-1)\\
f(n-2)\\
f(n-3)\\
\vdots\\
f(n-k)\\
sum(n-1)
\end{matrix}\right)
\]

则通过矩阵快速幂即可求直接得\(f(n)\)的前缀和。复杂度为高斯消元的复杂度\(O(k^3)\)加上矩阵快速幂的复杂度\(O(k^3\cdot log(n))\)。所以总复杂度为\(O(T\cdot k^3\cdot log(n))\)。约为\(4\times 10^8\)。

注意特判\(n\le 2\times k\)的情况


【Code】

  1. /*
  2. * @Author: Simon
  3. * @Date: 2019-09-19 20:19:56
  4. * @Last Modified by: Simon
  5. * @Last Modified time: 2019-09-21 20:14:34
  6. */
  7. #include<bits/stdc++.h>
  8. using namespace std;
  9. typedef int Int;
  10. #define int long long
  11. #define INF 0x3f3f3f3f
  12. const int mod=1e9+7;
  13. #define maxn 145
  14. #define maxm 145
  15. /*
  16. Author: Simon
  17. 返回自由变量个数,-1表示无解。
  18. 若矩阵的秩=增广矩阵的秩=变量个数,则有唯一解
  19. 若矩阵的秩=增广矩阵的秩<变量个数,则有无穷多解
  20. 若矩阵的秩<增广矩阵的秩,则无解
  21. 注:若用于开关问题,则使用注释部分。
  22. 复杂度: O(n^3)
  23. */
  24. const int/*开关问题:int*/ eps = 1e-10;
  25. // int n/*方程个数*/, m/*变量个数*/;
  26. int/*开关问题:int*/ a[maxn][maxn]/*增广矩阵(n*(m+1)),开关问题:a[i][j]表示与j关联的开关为i*/, x[maxn]/*解*/;
  27. int fpow(int a,int b,int mod){
  28. int ans=1;a%=mod;
  29. while(b){
  30. if(b&1) ans=1LL*ans*a%mod;
  31. a=1LL*a*a%mod;
  32. b>>=1;
  33. }
  34. return ans;
  35. }
  36. inline int sgn(int x) { return x?1:0; } //若x不接近0,返回1,否则返回0。
  37. int Gauss(int a[maxn][maxn]/*增广矩阵*/, int n/*方程个数*/, int m/*变量个数*/) {
  38. memset(x, 0, sizeof(x));
  39. int r = 0/*第r行*/, c = 0/*第c列*/;
  40. while (r < n && c < m) {/*化为上三角矩阵*/
  41. int m_r = r;
  42. for(int i=r+1;i<n;i++) if (abs(a[i][c]) > abs(a[m_r][c])) m_r = i; /*从第r行开始,找出第c列绝对值最大的 */
  43. if (m_r != r){
  44. for(int j=c;j<m+1;j++) swap(a[r][j], a[m_r][j]); /*将值最大的放到第r行*/
  45. }
  46. if (!sgn(a[r][c])) { /*判断a[r][c]是否为零*/
  47. a[r][c] = 0; ++c;
  48. continue;
  49. }
  50. for(int i=r+1;i<n;i++){ /*将第c列化为上三角*/
  51. if (a[i][c]) {
  52. int/*开关问题:int*/ t = 1LL*a[i][c]%mod*fpow(a[r][c]%mod,mod-2,mod)%mod;/*开关问题:删除*/
  53. for(int j=c;j<m+1;j++) a[i][j] = (a[i][j]-1LL*a[r][j]%mod * t%mod)%mod/*开关问题:a[i][j]^=a[r][j]*/;
  54. }
  55. }
  56. ++r; ++c;
  57. }
  58. for(int i=r;i<n;i++) if(sgn(a[i][m])) return -1;/*若xi=0,b!=0则无解*/
  59. for(int i=m-1;i>=0;i--){/*回代解方程组*/
  60. int/*开关问题:int*/ s = a[i][m];
  61. for(int j=i+1;j<m;j++) s = (s-1LL*a[i][j]%mod * x[j] % mod)%mod/*开关问题:s^=(a[i][j]&x[j])*/;
  62. x[i] = 1LL*s%mod * fpow(a[i][i],mod-2,mod)%mod/*开关问题:x[i]=s*/;
  63. }
  64. return 0;/*有唯一解*/
  65. }
  66. //Author: Simon
  67. struct Matrix{ //矩阵类
  68. int m[maxn][maxn];
  69. void clear(){
  70. for(int i=0;i<maxn;i++) for(int j=0;j<maxn;j++) m[i][j]=0;
  71. }
  72. Matrix(){
  73. clear();
  74. }
  75. void init(){
  76. for(int i=0;i<maxn;i++) m[i][i]=1;
  77. }
  78. void set(int len){ //构造矩阵,根据题目变化
  79. for(int i=0;i<len;i++){
  80. for(int j=i-1;j<=i+1;j++){
  81. if(j<0||j>=len) continue;
  82. m[i][j]=1;
  83. }
  84. }
  85. }
  86. int *operator [](int x){
  87. return m[x];
  88. }
  89. };
  90. Matrix mul(Matrix a,Matrix b,int n){
  91. Matrix c;
  92. for(int i=0;i<n;i++){
  93. for(int j=0;j<n;j++){
  94. for(int k=0;k<n;k++){
  95. c[i][j]=(c[i][j]+1LL*a[i][k]*b[k][j]%mod)%mod;
  96. }
  97. }
  98. }
  99. return c;
  100. }
  101. Matrix fpow(Matrix a,long long b,int k){
  102. // printf("b=%lld\n",b);
  103. Matrix c;c.init();
  104. while(b){
  105. if(b&1) c=mul(c,a,k);
  106. a=mul(a,a,k);
  107. b>>=1;
  108. }
  109. return c;
  110. }
  111. int t[maxn];
  112. Int main(){
  113. #ifndef ONLINE_JUDGE
  114. //freopen("input.in","r",stdin);
  115. //freopen("output.out","w",stdout);
  116. #endif
  117. ios::sync_with_stdio(false);
  118. cin.tie(0);
  119. int T;scanf("%lld",&T);
  120. while(T--){
  121. memset(a,0,sizeof(a));
  122. int k;long long n;scanf("%lld%lld",&k,&n);
  123. for(int i=1;i<=2*k;i++){
  124. scanf("%lld",t+i);
  125. }
  126. if(n<=2LL*k){ //特判
  127. long long _ans=0;
  128. for(int i=0;i<n;i++) _ans=(_ans+t[i])%mod;
  129. printf("%lld\n",_ans);
  130. continue;
  131. }
  132. for(int i=0;i<k;i++){
  133. for(int j=0;j<k;j++){
  134. a[i][j]=t[k+i-j];
  135. }
  136. }
  137. for(int i=0;i<k;i++) a[i][k]=t[i+1+k];
  138. Gauss(a,k,k); Matrix A;
  139. for(int i=0;i<k;i++) A[0][i]=x[i];
  140. for(int i=1;i<k;i++) A[i][i-1]=1;
  141. A[k][0]=1;A[k][k]=1;
  142. A=fpow(A,n-k,k+1);
  143. Matrix B;
  144. for(int i=0;i<k;i++){
  145. B[i][0]=t[k-i];
  146. B[k][0]+=t[i+1];
  147. }
  148. A=mul(A,B,k+1);
  149. printf("%lld\n",A[k][0]);
  150. }
  151. #ifndef ONLINE_JUDGE
  152. cout<<endl;system("pause");
  153. #endif
  154. return 0;
  155. }

2019-ACM-ICPC-沈阳区网络赛-K. Guanguan's Happy water-高斯消元+矩阵快速幂的更多相关文章

  1. ACM-ICPC 2018 焦作赛区网络预赛- L:Poor God Water(BM模板/矩阵快速幂)

    God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him t ...

  2. 2017 ACM/ICPC 南宁区 网络赛 Overlapping Rectangles

    2017-09-24 20:11:21 writer:pprp 找到的大神的代码,直接过了 采用了扫描线+线段树的算法,先码了,作为模板也不错啊 题目链接:https://nanti.jisuanke ...

  3. 6.10 省选模拟赛 小C的利是 高斯消元 矩阵行列式

    LINK:小C的利是 想起来把这道题的题解写了 .一个常识:利是在广东那边叫做红包. 关于行列式的题目 不过我不太会23333..口胡还是可以的. 容易想到10分的状压.不过没什么意思. 仔细观察要求 ...

  4. HDU 5833 (2016大学生网络预选赛) Zhu and 772002(高斯消元求齐次方程的秩)

    网络预选赛的题目……比赛的时候没有做上,确实是没啥思路,只知道肯定是整数分解,然后乘起来素数的幂肯定是偶数,然后就不知道该怎么办了… 最后题目要求输出方案数,首先根据题目应该能写出如下齐次方程(从别人 ...

  5. hdu 2157 从a点走到b点刚好k步的方案数是多少 (矩阵快速幂)

    n个点 m条路 询问T次 从a点走到b点刚好k步的方案数是多少 给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值把 给定的图转为邻接矩阵,即A(i,j)=1当且仅当存 ...

  6. 2019 ICPC南昌邀请赛 网络赛 K. MORE XOR

    说明 \(\oplus x​\)为累异或 $ x^{\oplus(a)}​$为异或幂 题意&解法 题库链接 $ f(l,r)=\oplus_{i=l}^{r} a[i]$ $ g(l,r)=\ ...

  7. HDU 5894 hannnnah_j’s Biological Test (组合数学) -2016 ICPC沈阳赛区网络赛

    题目链接 #include <map> #include <queue> #include <math.h> #include <stdio.h> #i ...

  8. 2014 ACM/ICPC 鞍山赛区网络赛(清华命题)

    为迎接10月17号清华命题的鞍山现场赛 杭电上的题目 Biconnected(hdu4997)     状态压缩DP Rotate(hdu4998)    相对任一点的旋转 Overt(hdu4999 ...

  9. HDU 5898 odd-even number (数位DP) -2016 ICPC沈阳赛区网络赛

    题目链接 题意:一个数字,它每个数位上的奇数都形成偶数长度的段,偶数位都形成奇数长度的段他就是好的.问[L , R]的好数个数. 题解:裸的数位dp, 从高到低考虑每个数位, 状态里存下到当前位为止的 ...

随机推荐

  1. shell每隔一秒钟就记录下netstat状态

    说明 木马可能类似随机发送心跳包的操作,随机sleep.对这类情况写好了一个监听shell脚本,每隔一秒钟就记录下netstat状态. 代码 #!/bin/bash #功能:用于定时执行lsof 和 ...

  2. 第七章 云原生生态的基石 Kubernetes

    7.1 Kubernetes架构 K8s的核心组件: etcd: 协同存储,负责保存整个集群的状态. API:资源操作的唯一入口. controller manager: 维护集群的状态,执行故障检测 ...

  3. 最新 企叮咚java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿. 企叮咚等10家互联网公司的校招Offer,因为某些自身原因最终选择了 企叮咚.6.7月主要是做系统复习.项目复盘.Leet ...

  4. JIRA问题状态已关闭,但是解决结果还是未解决

    自己设置的工作流,状态和解决结果是没有关联的,这时候我们要配置关联关系 1.如下,状态时已关闭,但是解决结果是未解决 . 2.解决方法: 2.1设置-问题-工作流,找到目前在使用的工作流,点击编辑 3 ...

  5. 微信小程序之一:动态添加view(view包含picker,input)

    <view wx:for="{{array}}" wx:key="this" class="borderContainer"> ...

  6. 转录组组装软件stringtie

    StringTie是約翰·霍普金斯大學计算机生物中心开发的一款转录组组装软件,在组装转录本的完整度,精度和速度方面都较以往的cufflinks 有很大的提升,也是目前有参考基因组转录组主流的组装软件. ...

  7. publish dotnet core angular spa app to docker

    公司一个使用Angular开发的应用准备下个版本使用.Net Core开发后台, 刚好可以用到.Net Core Angular Spa模板, 而且最近也在学习Docker, 于是就想把它融汇贯通, ...

  8. [C++] 非递归实现前中后序遍历二叉树

    目录 前置技能 需求描述 binarytree.h 具体实现 binarytree.cpp main.cpp 网上代码一搜一大片,大同小异咯. 书上的函数实现代码甚至更胜一筹,而且抄一遍就能用,唯一问 ...

  9. MySQL中的case when 中对于NULL值判断的坑

    sql中的case when 有点类似于Java中的switch语句,比较灵活,但是在Mysql中对于Null的处理有点特殊 Mysql中case when语法: 语法1: CASE case_val ...

  10. 微信小程序的页面跳转==编程式导航传参 和 标签的方法传参==以及如何过去传递过来的参数

    小程序导航传参接收传递过来的参数 在onload中 实例