2016 pku campusH/OpenJ_POJ - C16H(推公式+矩阵快速幂)

传送门:http://poj.openjudge.cn/practice/C16H?lang=en_US

  题面:描述

Wenwen has a magical ball. When put on an infinite plane, it will keep duplicating itself forever.

Initially, Wenwen puts the ball on the location (x0, y0) of the plane. Then the ball starts to duplicate itself right away. For every unit of time, each existing ball on the plane will duplicate itself, and the new balls will be put on the adjacent locations. The duplication rule of these balls is, during the i-th unit of time, a ball, which locates at (x, y), will duplicate ui balls to (x, y+1), di balls to (x, y-1), li balls to (x-1, y) and ri balls to (x+1, y).

The duplication rule has a period of M. In another words, ui=ui-M, di=di-M, li=li-M, ri=ri-M, for i=M+1,M+2,...

Wenwen is very happy because she will get many balls. It is easy to calculate how many balls she will get after N units of time. However, she wants to know the sum of x-coordinates and y-coordinates of all balls after N units of time. This is a bit difficult for her. Could you help her? Since the sum might be very large, you should give the sum modulo 1,000,000,007 to her.

输入The first line contains an integer T (1 ≤ T ≤ 25), indicating the number of test cases.

For each test case:

The first line contains four integers N (1 ≤ N ≤ 10^18), M (1 ≤ M ≤ 20,000), x0 and y0 (-10^18 ≤ x0,y0 ≤ 10^18);

Then follows M lines, the i-th line contains four integers: ui, di, li and ri (0 ≤ ui,di,li,ri ≤ 10,000).输出For each test case, output one integer on a single line, indicating the sum of x-coordinates and y-coordinates of all balls after N units of time, modulo 1,000,000,007.样例输入

1
2 2 1 1
2 0 0 0
0 0 0 1

样例输出

19

提示In the Sample Input:

Initially, there is 1 ball on (1,1).

After 1 unit of time, there is 1 ball on (1,1) and 2 balls on (1,2);

After 2 units of time, there is 1 ball on (1,1), 2 balls on (1,2), 1 ball on (2,1) and 2 balls on (2,2).

Therefore, after 2 units of time, the sum of x-coordinates and y-coordinates of all balls is
(1+1)*1+(1+2)*2+(2+1)*1+(2+2)*2=19.

题意:给你一个处于x0,y0的球,会进行周期为M的变化。第i分钟,所有的点会进行复制,使得会在(x,y+1)增加ui个球,在(x,y-1)处增加di个球,在(x-1,y)处增加li个球,在(x+1,y)处增加ri个球,问你在N时刻所有球的横纵坐标的和为多少。

题目分析:

对于这个题目,首先我们得发现虽然题目说不需要求总的小球的数量,但是,如果我们得知了小球的总量的话,就可以很好的对横纵坐标的和进行操作(只需要用总的个数乘上新增的个数,再加上前一个横纵坐标的和乘上新的坐标的和即可)。

因此我们就可以发现这道题的递推式:

对于总的小球的数量:

allball[i]= allball[i-1]*(1+u[i]+d[i]+l[i]+r[i]);

而对于总的横纵坐标的和:

sum[i]=allball[i-1]*(1+u[i]+d[i]+l[i]+r[i])+sum[i-1]*(u[i]-d[i]-k[i]+r[i]);

得到了递推的式子,我们就可以在O(n)的时间内求解出答案。但是对于这题来说,因为数据范围为1e18,因此毫无疑问必须是用含有log的算法,于是我们就可以通过矩阵快速幂进行优化。

而因为这个递推式是有一定的周期性的,因此,我们可以先求出第一个周期的矩阵,然后通过矩阵快速幂求出矩阵的(n/m)次幂,最后在乘上剩余的(n%m);

 

 1 #include <bits/stdc++.h>
 2 #define maxn 100005
 3 using namespace std;
 4 const int mod=1e9+7;
 5 typedef long long ll;
 6 struct Matrix{
 7     ll mo[2][2];
 8     Matrix(){
 9         memset(mo,0,sizeof(mo));
10     }
11 };
12 Matrix Mul(Matrix x,Matrix y){
13     Matrix c;
14     for(int i=0;i<2;i++){
15         for(int j=0;j<2;j++){
16             for(int k=0;k<2;k++){
17                 c.mo[i][j]=(c.mo[i][j]+x.mo[i][k]*y.mo[k][j])%mod;
18             }
19         }
20     }
21     return c;
22 }
23 Matrix powmod(Matrix x,ll n){
24     Matrix res;
25     for(int i=0;i<2;i++){
26         res.mo[i][i]=1;
27     }
28     while(n){
29         if(n&1) res=Mul(res,x);
30         n>>=1;
31         x=Mul(x,x);
32     }
33     return res;
34 }
35 int A[maxn];
36 int B[maxn];
37 int main()
38 {
39     int t;
40     scanf("%d",&t);
41     while(t--){
42         ll n,m,x0,y0;
43         scanf("%lld%lld%lld%lld",&n,&m,&x0,&y0);
44         x0=(x0%mod+mod)%mod;
45         y0=(y0%mod+mod)%mod;
46         for(int i=0;i<m;i++){
47             int a,b,c,d;
48             scanf("%d%d%d%d",&a,&b,&c,&d);
49             A[i]=1+a+b+c+d;
50             B[i]=a-b+d-c;
51         }
52         Matrix base;
53         for(int i=0;i<2;i++){
54             base.mo[i][i]=1;
55         }
56         for(int i=0;i<m;i++){
57             Matrix tmp;
58             tmp.mo[0][0]=tmp.mo[1][1]=A[i],tmp.mo[1][0]=B[i];
59             base=Mul(base,tmp);
60         }
61         base=powmod(base,n/m);
62         for(int i=0;i<n%m;i++){
63             Matrix tmp;
64             tmp.mo[0][0]=tmp.mo[1][1]=A[i],tmp.mo[1][0]=B[i];
65             base=Mul(base,tmp);
66         }
67         cout<<(base.mo[1][0]+base.mo[1][1]*(x0+y0))%mod<<endl;
68     }
69     return 0;
70 }

原文地址:https://www.cnblogs.com/Chen-Jr/p/8992081.html

时间: 2024-10-29 02:31:29

2016 pku campusH/OpenJ_POJ - C16H(推公式+矩阵快速幂)的相关文章

CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)

问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高位数字不为0. 因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301. 请计算恰好有n位的有趣的数的个数.由于答案可能非常大,只需要输出答案除以1000000007的余数. 输入格式 输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000). 输

HDU 4686 (推公式+矩阵快速幂)

题目连接:传送门 题意: 给定ai,bi的推倒公式,求sigma(ai*bi) ( 0<= i < n) 分析: A0 = A0 Ai = Ai-1*Ax+Ay B0 = B0 Bi = Bi-1*Bx+By 设Fi表示Ai*Bi Fi = Ai * Bi ===>    Fi = (Ai-1*Ax + Ay)*(Bi-1*Bx + By) ===>    Fi = Ax*Bx*(Ai-1*Bi-1) + Ax*By*Ai-1 + Bx*Ay*Bi-1 ===>    Fi

hihoCoder 1143 : 骨牌覆盖问题&#183;一(递推,矩阵快速幂)

[题目链接]:click here~~ 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题: 我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘.对于这个棋盘,一共有多少种不同的覆盖方法呢? 举个例子,对于长度为1到3的棋盘,我们有下面几种覆盖方式: 提示:骨牌覆盖 提示:如何快速计算结果 输入 第1行:1个整数N.表示棋盘长度.1≤N≤100,000,000 输出 第1行:1个整数,表示覆盖方案数 M

[HDOJ2604]Queuing(递推,矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604 递推式是百度的,主要是练习一下如何使用矩阵快速幂优化. 递推式:f(n)=f(n-1)+f(n-3)+f(n-4),其中f(0)=2, f(1)=4, f(2)=6, f(3)=9. 当n>4时候,需要通过这个关系来递推. 构造矩阵这种东西我以前一直认为是很玄学的,但是如果深入研究的话不难发现其实也有规律可循.这是一个齐次递推式,很好构造. 我们希望通过如下矩阵(1)得到矩阵(2) | f(n

[题解][SHOI2013]超级跳马 动态规划/递推式/矩阵快速幂优化

这道题... 让我见识了纪中的强大 这道题是来纪中第二天(7.2)做的,这么晚写题解是因为 我去学矩阵乘法啦啦啦啦啦对矩阵乘法一窍不通的童鞋戳链接啦 层层递推会TLE,正解矩阵快速幂 首先题意就是给你一个 n 行m 列 的格子图 一只马从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行. 题意很简单暴力dp的思路也很简单但是数据很恶心虽然远古一点,但毕竟是省选题 1 ≤ n ≤ 50,2 ≤ m ≤ 10^9 不过还是给了我们一点提示:n这么小? 总之我们先找出转移式对于每一个点

hdu 2604 Queuing(推推推公式+矩阵快速幂)

Description Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time. Now we define that 'f' is short for female and 'm' is

hdu2604 递推转换矩阵快速幂

刚开始还以为用位运算与或几下几个循环就搞定了,算着算着发现不行........ 还是一种固定的切题角度,我假设有长度为n,总的排列数位f(n),怎么算他呢?从后往前考虑,因为大多数情况,都是用前面的结果推后面的结果, 那么当第n位是m的时候,如果我知道f(n-1)等于多少,那么f(n-1)的排列+加一个m是不是就是f(n)的一部分解了?  对吧,以此类推,   当第n位为f的时候,可是fff,fmf不能连着 那是不是就剩下ffm,fmm的情况了,对于前者ffm,由于不能凑成ffmf的情况,所以只

「常系数齐次线性递推」——矩阵快速幂的优化

引入: 对于递推方程: $$F(x) = \sum_{i=1}^k a_iF(x-i)$$ 我们显然会得到一个关于$F$的多项式求逆或者矩阵递推式,大多数情况下我们都是用后者,但是当$k$很大的时候,$k^3log n$的时间复杂度我们是吃不消的,那么自然我们的前人就搞出了一些优化. 特征多项式及Cayley-Hamilton定理: 一.特征多项式的定义: 设$A$是$n$阶矩阵,若数$\lambda$和非零列向量$x$使关系式$$Ax=\lambda x\;\;\;\;\;(1)$$ 成立,那

poj 3734 矩阵快速幂+YY

题目原意:N个方块排成一列,每个方块可涂成红.蓝.绿.黄.问红方块和绿方块都是偶数的方案的个数. sol:找规律列递推式+矩阵快速幂 设已经染完了i个方块将要染第i+1个方块. a[i]=1-i方块中,红.绿方块数量都是偶数的方案数 b[i]=1-i方块中,红.绿方块数量一个是偶数一个是奇数的方案数(红even绿odd 或 红odd绿even) c[i]=1-i方块中,红.绿方块数量都是奇数的方案数 可以得出递推公式: a[i+1]=2*a[i]+b[i] b[i+1]=2*a[i]+2*b[i