冬令营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 ...
随机推荐
- "中台"论再议
前言:讲中台的太多了,好像似乎不提中台就没法在IT圈混,但对中台又缺少统一明确的定义,姑且听其言,择其精华.最近看到一篇将中台的,觉得还不错,记录下来,分享给大家. 硅谷的“中台论” 在国内创立智领云 ...
- 明解C语言 入门篇 第九章答案
练习9-1 /* 将字符串存储在数组中并显示(其2:初始化) */ #include <stdio.h> int main(void) { char str[] = "ABC\0 ...
- Docker修改已创建容器端口映射
修改已创建容器端口映射. 通过编辑 hostconfig.json 文件来修改 Docker 容器的端口映射 该文件地址:/var/lib/docker/containers/[hash_of_the ...
- C++分治策略实现二分搜索
问题描述: 给定已排好序的n个元素组成的数组,现要利用二分搜索算法判断特定元素x是否在该有序数组中. 细节须知: (1)由于可能需要对分治策略实现二分搜索的算法效率进行评估,故使用大量的随机数对算法进 ...
- golang学习笔记----并发
并发模型 并发目前来看比较主流的就三种: 多线程:每个线程一次处理一个请求,线程越多可并发处理的请求数就越多,但是在高并发下,多线程开销会比较大. 协程:无需抢占式的调度,开销小,可以有效的提高线程的 ...
- asp.net core MVC 入门学习
前言 .net core 已经更新到2.0以上的版本了,今天才开始正式接触,深为程序员,丢脸了,作为无所不能的IT人,我着手折腾一下这个跨平台的开发框架. (转载自百度百科).NET Core 是.N ...
- C# vb .NET读取识别条形码线性条码UPC-E
UPC-E是比较常见的条形码编码规则类型的一种.如何在C#,vb等.NET平台语言里实现快速准确读取该类型条形码呢?答案是使用SharpBarcode! SharpBarcode是C#快速高效.准确的 ...
- Markdown温故知新(2):详解七大标准语法
1.标题 2.强调(粗体 & 斜体) 3.列表 4.链接 & 图片 5.代码块 6.引用 7.分割线 8.总结 说明:在 Markdown 中,一行是指由换行符或回车符之外的字符构成的 ...
- PIE SDK 精度分析(分类后处理)
1.算法功能简介 遥感图像分类精度分析通常把分类图与标准数据进行比较,然后用正确分类的百分比来表示分类的精度. PIE SDK支持算法功能的执行,下面对精度分析算法功能进行介绍. 2.算法功能实现说明 ...
- validateField方法对部分表单字段进行校验
原文:https://blog.csdn.net/qq_37782076/article/details/85123602 代码 <template> <div class=&quo ...