2019-ACM-ICPC-沈阳区网络赛-K. Guanguan's Happy water-高斯消元+矩阵快速幂
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+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\)。则:
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)\):
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】
/*
* @Author: Simon
* @Date: 2019-09-19 20:19:56
* @Last Modified by: Simon
* @Last Modified time: 2019-09-21 20:14:34
*/
#include<bits/stdc++.h>
using namespace std;
typedef int Int;
#define int long long
#define INF 0x3f3f3f3f
const int mod=1e9+7;
#define maxn 145
#define maxm 145
/*
Author: Simon
返回自由变量个数,-1表示无解。
若矩阵的秩=增广矩阵的秩=变量个数,则有唯一解
若矩阵的秩=增广矩阵的秩<变量个数,则有无穷多解
若矩阵的秩<增广矩阵的秩,则无解
注:若用于开关问题,则使用注释部分。
复杂度: O(n^3)
*/
const int/*开关问题:int*/ eps = 1e-10;
// int n/*方程个数*/, m/*变量个数*/;
int/*开关问题:int*/ a[maxn][maxn]/*增广矩阵(n*(m+1)),开关问题:a[i][j]表示与j关联的开关为i*/, x[maxn]/*解*/;
int fpow(int a,int b,int mod){
int ans=1;a%=mod;
while(b){
if(b&1) ans=1LL*ans*a%mod;
a=1LL*a*a%mod;
b>>=1;
}
return ans;
}
inline int sgn(int x) { return x?1:0; } //若x不接近0,返回1,否则返回0。
int Gauss(int a[maxn][maxn]/*增广矩阵*/, int n/*方程个数*/, int m/*变量个数*/) {
memset(x, 0, sizeof(x));
int r = 0/*第r行*/, c = 0/*第c列*/;
while (r < n && c < m) {/*化为上三角矩阵*/
int m_r = r;
for(int i=r+1;i<n;i++) if (abs(a[i][c]) > abs(a[m_r][c])) m_r = i; /*从第r行开始,找出第c列绝对值最大的 */
if (m_r != r){
for(int j=c;j<m+1;j++) swap(a[r][j], a[m_r][j]); /*将值最大的放到第r行*/
}
if (!sgn(a[r][c])) { /*判断a[r][c]是否为零*/
a[r][c] = 0; ++c;
continue;
}
for(int i=r+1;i<n;i++){ /*将第c列化为上三角*/
if (a[i][c]) {
int/*开关问题:int*/ t = 1LL*a[i][c]%mod*fpow(a[r][c]%mod,mod-2,mod)%mod;/*开关问题:删除*/
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]*/;
}
}
++r; ++c;
}
for(int i=r;i<n;i++) if(sgn(a[i][m])) return -1;/*若xi=0,b!=0则无解*/
for(int i=m-1;i>=0;i--){/*回代解方程组*/
int/*开关问题:int*/ s = a[i][m];
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])*/;
x[i] = 1LL*s%mod * fpow(a[i][i],mod-2,mod)%mod/*开关问题:x[i]=s*/;
}
return 0;/*有唯一解*/
}
//Author: Simon
struct Matrix{ //矩阵类
int m[maxn][maxn];
void clear(){
for(int i=0;i<maxn;i++) for(int j=0;j<maxn;j++) m[i][j]=0;
}
Matrix(){
clear();
}
void init(){
for(int i=0;i<maxn;i++) m[i][i]=1;
}
void set(int len){ //构造矩阵,根据题目变化
for(int i=0;i<len;i++){
for(int j=i-1;j<=i+1;j++){
if(j<0||j>=len) continue;
m[i][j]=1;
}
}
}
int *operator [](int x){
return m[x];
}
};
Matrix mul(Matrix a,Matrix b,int n){
Matrix c;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int k=0;k<n;k++){
c[i][j]=(c[i][j]+1LL*a[i][k]*b[k][j]%mod)%mod;
}
}
}
return c;
}
Matrix fpow(Matrix a,long long b,int k){
// printf("b=%lld\n",b);
Matrix c;c.init();
while(b){
if(b&1) c=mul(c,a,k);
a=mul(a,a,k);
b>>=1;
}
return c;
}
int t[maxn];
Int main(){
#ifndef ONLINE_JUDGE
//freopen("input.in","r",stdin);
//freopen("output.out","w",stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int T;scanf("%lld",&T);
while(T--){
memset(a,0,sizeof(a));
int k;long long n;scanf("%lld%lld",&k,&n);
for(int i=1;i<=2*k;i++){
scanf("%lld",t+i);
}
if(n<=2LL*k){ //特判
long long _ans=0;
for(int i=0;i<n;i++) _ans=(_ans+t[i])%mod;
printf("%lld\n",_ans);
continue;
}
for(int i=0;i<k;i++){
for(int j=0;j<k;j++){
a[i][j]=t[k+i-j];
}
}
for(int i=0;i<k;i++) a[i][k]=t[i+1+k];
Gauss(a,k,k); Matrix A;
for(int i=0;i<k;i++) A[0][i]=x[i];
for(int i=1;i<k;i++) A[i][i-1]=1;
A[k][0]=1;A[k][k]=1;
A=fpow(A,n-k,k+1);
Matrix B;
for(int i=0;i<k;i++){
B[i][0]=t[k-i];
B[k][0]+=t[i+1];
}
A=mul(A,B,k+1);
printf("%lld\n",A[k][0]);
}
#ifndef ONLINE_JUDGE
cout<<endl;system("pause");
#endif
return 0;
}
2019-ACM-ICPC-沈阳区网络赛-K. Guanguan's Happy water-高斯消元+矩阵快速幂的更多相关文章
- 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 ...
- 2017 ACM/ICPC 南宁区 网络赛 Overlapping Rectangles
2017-09-24 20:11:21 writer:pprp 找到的大神的代码,直接过了 采用了扫描线+线段树的算法,先码了,作为模板也不错啊 题目链接:https://nanti.jisuanke ...
- 6.10 省选模拟赛 小C的利是 高斯消元 矩阵行列式
LINK:小C的利是 想起来把这道题的题解写了 .一个常识:利是在广东那边叫做红包. 关于行列式的题目 不过我不太会23333..口胡还是可以的. 容易想到10分的状压.不过没什么意思. 仔细观察要求 ...
- HDU 5833 (2016大学生网络预选赛) Zhu and 772002(高斯消元求齐次方程的秩)
网络预选赛的题目……比赛的时候没有做上,确实是没啥思路,只知道肯定是整数分解,然后乘起来素数的幂肯定是偶数,然后就不知道该怎么办了… 最后题目要求输出方案数,首先根据题目应该能写出如下齐次方程(从别人 ...
- hdu 2157 从a点走到b点刚好k步的方案数是多少 (矩阵快速幂)
n个点 m条路 询问T次 从a点走到b点刚好k步的方案数是多少 给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值把 给定的图转为邻接矩阵,即A(i,j)=1当且仅当存 ...
- 2019 ICPC南昌邀请赛 网络赛 K. MORE XOR
说明 \(\oplus x\)为累异或 $ x^{\oplus(a)}$为异或幂 题意&解法 题库链接 $ f(l,r)=\oplus_{i=l}^{r} a[i]$ $ g(l,r)=\ ...
- HDU 5894 hannnnah_j’s Biological Test (组合数学) -2016 ICPC沈阳赛区网络赛
题目链接 #include <map> #include <queue> #include <math.h> #include <stdio.h> #i ...
- 2014 ACM/ICPC 鞍山赛区网络赛(清华命题)
为迎接10月17号清华命题的鞍山现场赛 杭电上的题目 Biconnected(hdu4997) 状态压缩DP Rotate(hdu4998) 相对任一点的旋转 Overt(hdu4999 ...
- HDU 5898 odd-even number (数位DP) -2016 ICPC沈阳赛区网络赛
题目链接 题意:一个数字,它每个数位上的奇数都形成偶数长度的段,偶数位都形成奇数长度的段他就是好的.问[L , R]的好数个数. 题解:裸的数位dp, 从高到低考虑每个数位, 状态里存下到当前位为止的 ...
随机推荐
- 神啊,看看Log4Net这个东西吧
这个东西实在是让人感动的想哭囊…………-_-..... Log4Net.config文件 <?xml version="1.0" encoding="utf-8&q ...
- jvm(1)---java内存结构
jvm主要由三个子系统构成:类加载子系统,运行时数据区,执行引擎 运行时数据区主要包括: 1.本地方法栈:登记native方法,执行时加载本地方法库 2.程序计数器:就是一个指针,用来存储指向下一条执 ...
- [BJOI2019] 奥术神杖 [取log+AC自动机+dp]
题面 传送门 思路 首先,看到这个乘起来开根号的形式,应该能想到用取$\log$的方式做一个转化: $\sqrt[n]{\prod_i a_i}=\frac{1}{n}\sum_i \log_b a_ ...
- SQL触发器中的inserted表和deleted表
开发也有年头了,但是触发器确实用的比较少,但是无容置疑触发器确实不错, 最近项目要求需要用到的触发器特别多.频繁,觉得很有必要记录和积累下. 在触发器语句中用两个特殊的表一个是deleted表和ins ...
- burpsuite破解网页密码
1.暴力破解网页登录 http://jingyan.baidu.com/article/200957619c8739cb0721b4ff.html https://zhuanlan.zhihu.com ...
- sublime text3 修改快捷键为eclipse
Preferences -> Key bindings - User [ { "keys": ["shift+enter"], "command ...
- Session中清除对象方法比较
转载. https://blog.csdn.net/u014401141/article/details/51816308 Session中清除对象方法比较 http://blog.csdn.ne ...
- 10分钟搭建一个小型网页(python django)(hello world!)
10分钟搭建一个小型网页(python django)(hello world!) 1.安装django pip install django 安装成功后,在Scripts目录下存在django-ad ...
- Elastic Search快速上手(2):将数据存入ES
前言 在上手使用前,需要先了解一些基本的概念. 推荐 可以到 https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.htm ...
- es6☞对象的解构赋值
变量必须与属性同名 let {name, age} = {name: 'wang', age: 22}; console.log(name, age); //wang 22 let {name} = ...