题目描述 Description
   生活中,我们常常用 233 表示情感。实际上,我们也会说 2333,23333,等等。 于是问题来了: 定义一种矩阵,称为 233 矩阵。矩阵的第一行依次是 23, 233,2333,23333,等。 此外,对矩阵的第 i 行、第 j 列的元素有 a[i][j] = a[i-1][j] + a[i][j-1],若 i, j 均大于 1。
 告诉了你矩阵第一列的第 2~n 个元素,你能否算出矩阵的第 n 行、第 m 列的元素呢?
输入描述 Input Description

输入文件包含多组数据(不超过 3 组),每组数据的格式如下:
第一行,两个整数 n, m。
第二行,n-1 个整数,依次是 a[2][1], a[3][1], …, a[n][1],表示矩阵第一列的第 2~n 个元素。(而 a[1][1] = 23,a[1][2] = 233,a[1][3] = 2333,以此类推)

输出描述 Output Description
输出若干行,每行一个整数,依次表示每组数据的答案模 10000007 后的结果。
样例输入 Sample Input
2 2
1
3 3
0 0
4 8
23 47 16
样例输出 Sample Output
234
2799
72937
数据范围及提示 Data Size & Hint
50% 的测试数据,1 <= m <= 10^6.
100% 的测试数据,1 <= n <= 11,2 <= m <= 10^9,0 <= a[i][1] <= 10^8.

考试时候第一反应骗50分走人,然后果真就骗五十分走人了,想都没想,现在想起十分后悔。

注意到m范围贼大,普通数组肯定存不下,而n的范围那么小,肯定就能想到矩阵快速幂。

对于第一行f(1,i)=10*f(1,i-1)+3,其中f(1,1)=23,以后的行f(i,j)=f(i-1,j)+f(i,j-1);

先设计一个目标矩阵,我们要得到f(n,m)的值,根据套路,那就把f(1,m),f(2,m)...f(n,m)当成一个目标矩阵吧,这个矩阵由f(1,m-1),f(2,m-1)..f(n,m-1)转移而来,根据转移方程以及矩阵乘法规则,我们能很容易找到转移矩阵,这个矩阵大概是这样:

10

0

0

0

0

3

10

1

0

0

0

3

10

1

1

0

0

3

10

1

1

1

0

3

10

1

1

1

1

3

0

0

0

0

0

1

至于最后一行是什么鬼,我们注意到第一行递推式f(1,i)=10*f(1,i-1)+3中那个3很难搞,于是我们就在目标矩阵中最下面再来一个1,这样乘法就方便多了。

当然,上面那个矩阵是不唯一的,当n不同时,矩阵的样子也不同,但都是有规律的。然后,我们对于每一组数据,构造出一组转移矩阵,然后初始的矩阵也很好搞,然后快速幂一波就好了。下面是代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long LL;
#define MOD 10000007
inline int read()
{
int x=,f=;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)){x=x*+c-'';c=getchar();}
return x*f;
}
struct matrix
{
int x,y,a[][];//x为列数,y为行数,a[i][j]表示在矩阵中第i-1行,j-1列的数
matrix(){x=y=;memset(a,,sizeof(a));}
matrix operator = (const matrix &s)
{
x=s.x;y=s.y;
memcpy(a,s.a,sizeof(s));
return *this;
}
matrix operator * (const matrix &s)const
{
matrix c;c.y=y;c.x=s.x;
for(int i=;i<c.y;i++)
for(int j=;j<c.x;j++)
for(int k=;k<x;k++)
{
LL tmp=(LL)(a[i][k]%MOD)*(LL)(s.a[k][j]%MOD);
c.a[i][j]=(c.a[i][j]+tmp%MOD)%MOD;//此处一定要多多小心,防止int*int爆炸
}
return c;
}
};
int n,m,ans,mat[];
matrix mod_pow(matrix C,int n)
{
matrix ret=C,tmp=C;n--;
while(n)
{
if(n&)ret=ret*tmp;
tmp=tmp*tmp;
n>>=;
}
return ret;
}
int main()
{
freopen("matrix.in","r",stdin);
freopen("matrix.out","w",stdout);
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=;i<n;i++)mat[i]=read()%MOD;
matrix A;A.x=;A.y=n+;A.a[][]=;//构造初始矩阵
for(int i=;i<n;i++)A.a[i][]=mat[i];A.a[n][]=;
matrix B;B.x=n+;B.y=n+;//构造转移矩阵
for(int i=;i<n;i++)B.a[i][]=,B.a[i][n]=;
B.a[n][n]=;
for(int i=;i<n;i++)
for(int j=;j<=i;j++)B.a[i][j]=;
matrix final=mod_pow(B,m-)*A;
printf("%d\n",final.a[n-][]);
}
return ;
}

这是我第一次用结构体写矩阵,认为很好使。以后就用这个了。以下是模板,还附带一个可调试的print函数,可输出矩阵:

 struct matrix
{
int x,y,a[][];//x为列数,y为行数,a[i][j]表示在矩阵中第i-1行,j-1列的数
matrix(){x=y=;memset(a,,sizeof(a));}
matrix operator = (const matrix &s)
{
x=s.x;y=s.y;
memcpy(a,s.a,sizeof(s));
return *this;
}
matrix operator * (const matrix &s)const
{
matrix c;c.y=y;c.x=s.x;
for(int i=;i<c.y;i++)
for(int j=;j<c.x;j++)
for(int k=;k<x;k++)
{
LL tmp=(LL)(a[i][k]%MOD)*(LL)(s.a[k][j]%MOD);
c.a[i][j]=(c.a[i][j]+tmp%MOD)%MOD;
}
return c;
}
};
matrix mod_pow(matrix C,int n)
{
matrix ret=C,tmp=C;n--;
while(n)
{
if(n&)ret=ret*tmp;
tmp=tmp*tmp;
n>>=;
}
return ret;
}
void print(matrix A)
{
for(int i=;i<A.y;i++)
{
for(int j=;j<A.x;j++)printf("%d ",A.a[i][j]);
printf("\n");
}
}

冬令营DAY3 T1 Matrix的更多相关文章

  1. FJ省队集训DAY3 T1

    思路:我们考虑如果取掉一个部分,那么能影响到最优解的只有离它最近的那两个部分. 因此我们考虑堆维护最小的部分,离散化离散掉区间,然后用线段树维护区间有没有雪,最后用平衡树在线段的左右端点上面维护最小的 ...

  2. XJOI网上同步训练DAY3 T1

    思路:看来我真是思博了,这么简单的题目居然没想到,而且我对复杂度的判定也有点问题.. 首先我们选了一个位置i的b,那一定只对i和以后的位置造成改变,因此我们可以这样看: 我们从前往后选,发现一个位置的 ...

  3. 2016NOI冬令营day3

    上午第一课堂  第一次感觉能听... IOI题目选讲挺不错的,比较有趣(yong4) :) 然而接下来的“基础”数据结构就太神了,完全不会QAQ :( 下午我听得比较认真,VFK讲的是下一代评测系统 ...

  4. @雅礼集训01/10 - T1@ matrix

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个矩阵.求它的所有子矩阵中本质不同的行的个数之和. inp ...

  5. 暑期培训7日游解题思路(day1~day3)

    暑期培训7日游解题思路(day1~day3) day1 第一天,王聿中老师出的题目比较简单,T1很水,T2是个简单的DP,T3还是有一点意思的.在网格图中删掉若干条边,使得所有格子都联通,求删掉的边的 ...

  6. [冬令营模拟]GTSG2018

    上学期没有去 GTSG,于是今天老师让我们来做一下 GTSG2018 Day1 & Day3 Day1 在上午当成一场考试来搞了,Day3 由于锅太多而且 T3 玄学而被放到下午自学... 上 ...

  7. bjwc Day3 & 4 妈妈我这是来了个什么地方呀

    真·bjwc开始了 Day3 T1啥啥啥 第k大斜率?想都没想码了个暴力,然后爆零...暴力都能错,退役 T2看着像网络流就扔了个网络流大暴力上去,六七十分的样子然后蜜汁wa T3题面说“想都没想就弄 ...

  8. noip2018 pre——Dp

    Dp专题 1011: KC的瓷器 (porcelain) 题目描述 KC来到了一个盛产瓷器的国度.他来到了一位商人的店铺.在这个店铺中,KC看到了一个有n(1<=n<=100)排的柜子,每 ...

  9. COJ 0016 20603矩阵链乘

    传送门:http://oj.cnuschool.org.cn/oj/home/solution.htm?solutionID=35454 20603矩阵链乘 难度级别:B: 运行时间限制:1000ms ...

随机推荐

  1. 阿里巴巴 Java 开发手册 1.4.0

    一.编程规约(一) 命名风格1. [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束.反例: _name / __name / $name / name_ / name$ ...

  2. python运维开发常用模块(二)IPy

    1.安装 IP地址规划是网络设计中非常重要的一个环节,规划的好坏会直 接影响路由协议算法的效率,包括网络性能.可扩展性等方面,在这个 过程当中,免不了要计算大量的IP地址,包括网段.网络掩码.广播地 ...

  3. Dart:2.通过一个简单程序来理解Dart基础语法

    一 . 一个简单的 Dart 程序 // 这是程序执行的入口. main() { var number = 42; // 定义并初始化一个变量. printNumber(number); // 调用一 ...

  4. 关于NB-IoT,没有比这篇更通俗易懂的啦!

    来源:内容来自「鲜枣课堂」,谢谢. 大家好,我是小枣君. 今天,我是来“吹NB”的.嗯,标题已经剧透了,这个NB,就是NB-IoT. 在过去的一年多,NB-IoT真的可以说是大红大紫.在通信圈里,除了 ...

  5. Nacos配置中心

    本文介绍spring cloud 集成 nacos案例 官方文档:https://nacos.io/zh-cn/docs/what-is-nacos.html](https://nacos.io/zh ...

  6. windows下生成ssl

    1.安装git window 需要安装 git 按部就班即可 https://git-scm.com/ 2.安装完之后,打开 Git Bash 输入以下命令并执行,然后一路按“回车”即可,效果见图: ...

  7. webapi 集成NLog

    参考项目代码:SwaggerDemoApi 安装 打开nuget管理器--->搜索nlog,安装箭头所指的两个文件到你的项目中,config安装到你的API项目即可,nlog文件安装到你用得到n ...

  8. Centos7 Putty SSH密钥登录

    在本地电脑打开PuTTYgen程序,点击Generate生成密钥,可以再设置一层密码,保存公钥和私钥到本地文件,保存好,最好多处备份 先用密码登录远程Centos vim ~/.ssh/authori ...

  9. 前后端分离项目Vue+drf开发部署总结

    思维导图xmind文件:https://files-cdn.cnblogs.com/files/benjieming/%E5%89%8D%E5%90%8E%E7%AB%AF%E5%88%86%E7%A ...

  10. JS树结构转list结构

    树转list /** * 树转list */ function treeToList(tree){ for(var i in tree){ var node = tree[i]; list = []; ...