冬令营DAY3 T1 Matrix
|
题目描述 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 组),每组数据的格式如下: |
|
输出描述 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的更多相关文章
- FJ省队集训DAY3 T1
思路:我们考虑如果取掉一个部分,那么能影响到最优解的只有离它最近的那两个部分. 因此我们考虑堆维护最小的部分,离散化离散掉区间,然后用线段树维护区间有没有雪,最后用平衡树在线段的左右端点上面维护最小的 ...
- XJOI网上同步训练DAY3 T1
思路:看来我真是思博了,这么简单的题目居然没想到,而且我对复杂度的判定也有点问题.. 首先我们选了一个位置i的b,那一定只对i和以后的位置造成改变,因此我们可以这样看: 我们从前往后选,发现一个位置的 ...
- 2016NOI冬令营day3
上午第一课堂 第一次感觉能听... IOI题目选讲挺不错的,比较有趣(yong4) :) 然而接下来的“基础”数据结构就太神了,完全不会QAQ :( 下午我听得比较认真,VFK讲的是下一代评测系统 ...
- @雅礼集训01/10 - T1@ matrix
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个矩阵.求它的所有子矩阵中本质不同的行的个数之和. inp ...
- 暑期培训7日游解题思路(day1~day3)
暑期培训7日游解题思路(day1~day3) day1 第一天,王聿中老师出的题目比较简单,T1很水,T2是个简单的DP,T3还是有一点意思的.在网格图中删掉若干条边,使得所有格子都联通,求删掉的边的 ...
- [冬令营模拟]GTSG2018
上学期没有去 GTSG,于是今天老师让我们来做一下 GTSG2018 Day1 & Day3 Day1 在上午当成一场考试来搞了,Day3 由于锅太多而且 T3 玄学而被放到下午自学... 上 ...
- bjwc Day3 & 4 妈妈我这是来了个什么地方呀
真·bjwc开始了 Day3 T1啥啥啥 第k大斜率?想都没想码了个暴力,然后爆零...暴力都能错,退役 T2看着像网络流就扔了个网络流大暴力上去,六七十分的样子然后蜜汁wa T3题面说“想都没想就弄 ...
- noip2018 pre——Dp
Dp专题 1011: KC的瓷器 (porcelain) 题目描述 KC来到了一个盛产瓷器的国度.他来到了一位商人的店铺.在这个店铺中,KC看到了一个有n(1<=n<=100)排的柜子,每 ...
- COJ 0016 20603矩阵链乘
传送门:http://oj.cnuschool.org.cn/oj/home/solution.htm?solutionID=35454 20603矩阵链乘 难度级别:B: 运行时间限制:1000ms ...
随机推荐
- AbstractExecutorService源码
public class RunnableFutureTask { static FinalizableDelegatedExecutorService executorService = (Fina ...
- vertica创建新用户并授权
1.创建用户,并设置密码: create user user1 identified by 'pwd1'; 2.把角色授权给用户(dbduser是普通角色): grant dbduser to use ...
- html 四种定位含义
技术过段时间不用的话就会忘记,需要复习一下 1.static:默认值.没有定位,元素出现在正常的流中(忽略top,bottom,left,right或者z-index声明). 2.relative:生 ...
- 解决mac/win双系统,mac原生读写NTFS分区重启后失效的问题
安装mac/win双系统,然后在mac下启用原生的NTFS分区读写功能,并将分区创建桌面快捷方式后,会发现有时候进入win后再进mac,原来创建的分区桌面快捷方式是白色的图标,并且分区也无法打开,这个 ...
- python__系统 : 线程池
参考文档: https://www.jianshu.com/p/b9b3d66aa0be 使用 ThreadPoolExecutor 类, as_completed 是迭代器, 如果有任务执行完 ...
- THUPC2019/CTS2019/APIO2019自闭记
自闭了,自闭选手不配拥有游记.
- 前端学习:学习笔记(JS部分)
前端学习:学习笔记(JS部分) 前端学习:JS学习总结(图解) JS的简介 JS基本语法 JS内置对象 JS的函数 JS的事件 JS的BOM JS的DOM JS的简介 新建步骤 <body ...
- 单片机成长之路(51基础篇)- 024 基于 N76E003 的按键按键状态机
前端时间要用按键,搞了个状态机(如图): main.c #include <N76E003.H> #include <SFR_Macro.h> //N76E003 SFR寄存器 ...
- 2019-11-29-win7-无法启动-WPF-程序-D3Dcompiler_47.dll-丢失
原文:2019-11-29-win7-无法启动-WPF-程序-D3Dcompiler_47.dll-丢失 title author date CreateTime categories win7 无法 ...
- C# 身份证号码15位和18位验证
/// <summary> /// 身份证 /// </summary> [Serializable] public class IDCard { /// <su ...