【矩阵---求A的1到N次幂之和】
引例: Matrix Power Series:
题目大意,给定矩阵A,求A^+A^+A^+...A^N。
题解:已知X=a,可以通过以下矩阵求出ans=a^+a^+...a^N ans=矩阵^n后第一行之和-=矩阵^(n+)后右上格的和-。
同理:矩阵也可以,只需要把1改为单位矩阵元即可。
左图a是常数,1就是1; 右图A是矩阵,1是单位元矩阵(主对角线是1)。
代码1:矩阵^N,第一行之和-1。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
int N,K,Mod;
struct mat
{
int mp[maxn][maxn],len;
mat(int x){ len=x; memset(mp,,sizeof(mp)); }
mat friend operator *(mat a,mat b)
{
mat res(a.len);
for(int k=;k<=res.len;k++)
for(int i=;i<=res.len;i++)
for(int j=;j<=res.len;j++)
res.mp[i][j]=(res.mp[i][j]+a.mp[i][k]*b.mp[k][j])%Mod;
return res;
}
mat friend operator ^(mat a,int x)
{
mat res(a.len);
for(int i=;i<=res.len;i++) res.mp[i][i]=;
while(x){
if(x&)res=res*a; a=a*a; x>>=;
} return res;
}
};
int main()
{
scanf("%d%d%d",&N,&K,&Mod);
mat array(N+N);
for(int i=;i<=N;i++)
for(int j=;j<=N;j++){
scanf("%d",&array.mp[i][j]);
}
for(int i=;i<=N;i++) array.mp[i][i+N]=array.mp[i+N][i+N]=;
array=array^(K);
for(int i=;i<=N;i++) array.mp[i][i+N]-=;
for(int i=;i<=N;i++){
for(int j=;j<N;j++)
printf("%d ",(array.mp[i][j]+array.mp[i][j+N]+Mod)%Mod);
printf("%d\n",(array.mp[i][N]+array.mp[i][N+N]+Mod)%Mod);
}
return ;
}
代码2:矩阵^N+1,右上格之和-1。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
int N,K,Mod;
struct mat
{
int mp[maxn][maxn],len;
mat(int x){ len=x; memset(mp,,sizeof(mp)); }
mat friend operator *(mat a,mat b)
{
mat res(a.len);
for(int k=;k<=res.len;k++)
for(int i=;i<=res.len;i++)
for(int j=;j<=res.len;j++)
res.mp[i][j]=(res.mp[i][j]+a.mp[i][k]*b.mp[k][j])%Mod;
return res;
}
mat friend operator ^(mat a,int x)
{
mat res(a.len);
for(int i=;i<=res.len;i++) res.mp[i][i]=;
while(x){
if(x&)res=res*a; a=a*a; x>>=;
} return res;
}
};
int main()
{
scanf("%d%d%d",&N,&K,&Mod);
mat array(N+N);
for(int i=;i<=N;i++)
for(int j=;j<=N;j++){
scanf("%d",&array.mp[i][j]);
}
for(int i=;i<=N;i++) array.mp[i][i+N]=array.mp[i+N][i+N]=;
array=array^(K+);
for(int i=;i<=N;i++) array.mp[i][i+N]-=;
for(int i=;i<=N;i++){
for(int j=;j<N;j++)
printf("%d ",(array.mp[i][j+N]+Mod)%Mod);
printf("%d\n",(array.mp[i][N+N]+Mod)%Mod);
}
return ;
}
代码3:利用二分。
--------------------分界线---------------------------
例题:HDU2243:考研路茫茫——单词情结
题意:问长度位1到L的所有单词中,有多少个不含给出的几个单词。
思路:利用矩阵得到可以26的1到N次幂。然后利用AC自动机得到基本矩阵X,再利用矩阵得到得到X^+X^+X^...X^N。
比如得到26的0到N次幂和,就有矩阵a[][]=,a[][]=,a[][]=,a[][]=;
矩阵^N后,第一行的和就是答案。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ull unsigned long long
const int maxn=;
int ch[maxn][],cnt;
int q[maxn],head,tail,Next[maxn],tag[maxn];
char s[];
struct mat
{
ull mp[maxn][maxn];
mat(){memset(mp,,sizeof(mp));}
mat init(){ memset(mp,,sizeof(mp));}
mat friend operator *(mat a,mat b)
{
mat res;
for(int k=;k<=max(cnt,);k++)
for(int i=;i<=max(cnt,);i++)
for(int j=;j<=max(cnt,);j++)
res.mp[i][j]+=a.mp[i][k]*b.mp[k][j];
return res;
}
mat friend operator ^(mat a,int x)
{
mat res;
for(int i=;i<=cnt;i++)
res.mp[i][i]=;
while(x){
if(x&) res=res*a;
a=a*a; x>>=;
} return res;
}
}; mat array; struct ACautom
{
void update()
{
cnt=head=tail=;
memset(Next,,sizeof(Next));
memset(tag,,sizeof(tag));
memset(ch,,sizeof(ch));
array.init();
}
void insert()
{
int Now=;
for(int i=;s[i];i++){
int x=s[i]-'a';
if(!ch[Now][x]) ch[Now][x]=++cnt;
Now=ch[Now][x];
} tag[Now]=;
}
void build()
{
for(int i=;i<;i++){
if(ch[][i]) q[++head]=ch[][i];
if(!tag[ch[][i]]) array.mp[][ch[][i]]++;
}
while(tail<head){
int u=q[++tail];
for(int i=;i<;i++){
if(ch[u][i]){
q[++head]=ch[u][i];
Next[ch[u][i]]=ch[Next[u]][i];
if(tag[Next[ch[u][i]]]) tag[ch[u][i]]=;
}
else ch[u][i]=ch[Next[u]][i];
if(!tag[ch[u][i]]) array.mp[u][ch[u][i]]++;
}
}
cnt++;
for(int i=;i<=cnt;i++) array.mp[i][cnt]=;
}
void qpow(int K)
{
ull ans,res=;
mat base;
base.mp[][]=; base.mp[][]=;
base.mp[][]=; base.mp[][]=;
base=base^K;
ans=base.mp[][]+base.mp[][];
array=array^K;
for(int i=;i<=cnt;i++) res=res+array.mp[][i];
cout<<ans-res<<endl;
}
}Trie;
int main()
{
int N,K;
while(~scanf("%d%d",&N,&K)){
Trie.update();
for(int i=;i<=N;i++) {
scanf("%s",s);
Trie.insert();
}
Trie.build();
Trie.qpow(K);
}
return ;
}
【矩阵---求A的1到N次幂之和】的更多相关文章
- [zt]矩阵求导公式
今天推导公式,发现居然有对矩阵的求导,狂汗--完全不会.不过还好网上有人总结了.吼吼,赶紧搬过来收藏备份. 基本公式:Y = A * X --> DY/DX = A'Y = X * A --&g ...
- Ipad,IPhone(矩阵求递推项+欧拉定理)
Ipad,IPhone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- AI 矩阵求导
矩阵求导 参考链接: https://en.wikipedia.org/wiki/Matrix_calculus#Scalar-by-vector_identities
- CodeForces 702B Powers of Two【二分/lower_bound找多少个数/给出一个数组 求出ai + aj等于2的幂的数对个数】
B. Powers of Two You are given n integers a1, a2, ..., an. Find the number of pairs of indexes i, ...
- MATLAB矩阵求值和稀疏矩阵
方阵的行列式: det(A) 矩阵线性无关的行数或列数,称为矩阵的秩. rank(A) 求3~20阶魔方矩阵的秩 for n=3:20 rank(magic(n)) end 矩阵的迹等于矩阵的对角线元 ...
- Tutte矩阵求一般图最大匹配
[集训队2017论文集] 一张无向图的Tutte矩阵为 其中xi,j为一个random的值. Tutte矩阵的秩(一定为偶数)/2 就是这张图的最大匹配. 原理大概就是: 一个图有完美匹配,则det( ...
- 笔试算法题(26):顺时针打印矩阵 & 求数组中数对差的最大值
出题: 输入一个数字矩阵,要求从外向里顺时针打印每一个数字: 分析: 从外向里打印矩阵有多重方法实现,但最重要的是构建合适的状态机,这样才能控制多重不同的操作: 注意有四种打印模式(左右,上下,右左, ...
- POJ 3233 Matrix Power Series(构造矩阵求等比)
Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak. ...
- 行列有序矩阵求第k大元素
问题来源:http://www.careercup.com/question?id=6335704 问题描述: Given a N*N Matrix. All rows are sorted, and ...
随机推荐
- Codeforces 849B Tell Your World (计算几何)
题目链接 Tell Your World 题意 给出N个点(i, xi),问是否存在两条平行的直线,使得每一个点恰好在两条直线的其中一条上. 每条直线必须穿过至少一个点. 考虑每个点和第1个点的斜率, ...
- Mac OS X 下安装python的MySQLdb模块
参考资料: mac os x下python安装MySQLdb模块 http://www.codeif.com/post/1073/ MAC OSX使用Python安装模块有关问题 http:// ...
- luogu P2912 [USACO08OCT]牧场散步Pasture Walking
题目描述 The N cows (2 <= N <= 1,000) conveniently numbered 1..N are grazing among the N pastures ...
- C# 读写bat文件
读: var batFile = "D:\\test.bat"; if (File.Exists(batFile)) { using (var sr = new StreamRea ...
- Spring启动流程
首先,对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境: 其次,在web.xm ...
- 用 jQuery实现图片等比例缩放大小
原文:http://www.open-open.com/code/view/1420975773093 <script type="text/javascript"> ...
- iOS开发 清除电话号码中的其他符号
最近从通讯录读取电话号码,读出得号码如:134-1814-****. 而我需要的为11位纯数字,一直找方法解决此问题,今天终于找到了.. 分享一下…… 代码如下: NSString *original ...
- Fragment 生命周期怎么来的?
前言 Fragment对于 Android 开发人员来说一点都不陌生,由于差点儿不论什么一款 app 都大量使用 Fragment,所以 Fragment 的生命周期相信对于大家来说应该都非常清晰.但 ...
- 增强版的RecycleViewAdapter,能够直接使用
在Android的项目中.须要大量的列表组件来显示数据.在之前的项目中一直使用的是ListView 组件,可是在最新的V7包中出现了能后替代ListView的组件RecycleView. 所以在新的项 ...
- 在线API
JExcelApi http://jexcelapi.sourceforge.net/resources/javadocs/index.html Poi http://poi.apache.org/a ...