NOI模拟题4 Problem B: 小狐狸(fox)

Solution
考虑分开统计朝向每一个方向的所有狐狸对答案的贡献. 比如说以向右为例, 我们用箭标表示每一只狐狸的方向, 用\('\)表示当前一步移动之前的每一只狐狸的位置.
\sum_{d_i = \rightarrow} x_iy_i &= \left( \sum_{d_i = \rightarrow} S \times (x_i' + 1)y_i' \right) + \left( \sum_{d_i = \uparrow} L \times x_i'y_i' \right) + \left( \sum_{d_i = \downarrow} R \times x_i' y_i' \right) \\
&= \left( \sum_{d_i = \rightarrow} S \times x_i'y_i' \right) + \left( \sum_{d_i = \rightarrow} S \times y_i' \right) + \left( \sum_{d_i = \uparrow} L \times x_i'y_i' \right) + \left( \sum_{d_i = \downarrow} R \times x_i' y_i' \right)
\end{aligned}
\]
这样一来, 我们发现只需要统计朝向每个方向的狐狸的\(\sum x\), \(\sum y\), \(\sum xy\)即可. 考虑怎么更新这几个值: 我们再多记录一个\(sum\)表示朝向每个方向的狐狸的数量.
然后我们就得到了\(4 \times 4 = 16\)个需要维护的变量.
我们建立一个\(16 \times 16\)的矩阵, 用于使得这些变量相互转移.
矩阵快速幂.
构建这个矩阵还是挺麻烦的.
总结: DP的优化除了常见的斜率/优先队列外, 不要忘了还有矩乘可用.
#include <cstdio>
#include <cstring>
const long long mv[4][2] = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
const long long MOD = 1e9 + 7;
struct matrix
{
long long a[16][16];
inline void build(long long S, long long L, long long R)
{
memset(a, 0, sizeof(a));
for (long long i = 0; i < 4; ++ i)
{
for (long long j = 0; j < 4; ++ j)
a[4 * i | j][4 * i | j] += S,
a[4 * i | j][4 * ((i - 1 + 4) % 4) | j] += R,
a[4 * i | j][4 * ((i + 1 + 4) % 4) | j] += L;
for (long long j = 0; j < 2; ++ j)
a[4 * i | j][4 * i | 2] = (a[4 * i | j][4 * i | 2] + S * mv[i][j] + MOD) % MOD,
a[4 * i | 3][4 * i | j] = (a[4 * i | 3][4 * i | j] + S * mv[i][! j] + MOD) % MOD;
}
/* for (long long i = 0; i < 16; ++ i)
{
for(long long j = 0; j < 16; ++ j) prlong longf("%d ", a[i][j]);
puts("");
} */
}
inline matrix friend operator *(matrix a, matrix b)
{
matrix res; memset(res.a, 0, sizeof res.a);
for (long long i = 0; i < 16; ++ i) for (long long j = 0; j < 16; ++ j) for (long long k = 0; k < 16; ++ k)
res.a[i][j] = (res.a[i][j] + a.a[i][k] * b.a[k][j] % MOD) % MOD;
return res;
}
}trans, a;
inline matrix power(long long x)
{
matrix res; memset(res.a, 0, sizeof res.a);
for (long long i = 0; i < 16; ++ i) res.a[i][i] = 1;
for (; x; trans = trans * trans, x >>= 1)
if (x & 1) res = res * trans;
return res;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("fox.in", "r", stdin);
freopen("fox.out", "w", stdout);
#endif
long long T; scanf("%d", &T);
for(long long cs = 0; cs < T; ++ cs)
{
long long t, S, L, R; scanf("%lld%lld%lld%lld", &t, &S, &L, &R);
trans.build(S, L, R);
matrix res = power(t);
long long ans = 0;
for (long long i = 3; i < 16; i += 4) ans = (ans + res.a[i][2]) % MOD;
printf("%d\n", ans);
}
}
NOI模拟题4 Problem B: 小狐狸(fox)的更多相关文章
- NOI模拟题1 Problem A: sub
题面 Sample Input 5 7 2 -1 -3 1 1 1 2 1 3 3 4 3 5 2 1 3 0 2 1 2 1 2 1 1 -3 2 Sample Output 2 4 5 2 HIN ...
- NOI模拟题6 Problem C: Circle
Solution 首先这个矩阵, 很明显的就是Vandermonde矩阵. 我们有公式: \[ |F_n| = \prod_{1 \le j < i \le n} (a_i - a_j) \] ...
- NOI模拟题5 Problem A: 开场题
Solution 注意到\(\gcd\)具有结合律: \[ \gcd(a, b, c) = \gcd(a, \gcd(b, c)) \] 因此我们从后往前, 对于每个位置\(L\), 找到每一段不同的 ...
- NOI模拟题4 Problem C: 填格子(board)
Solution 首先我们要有敏锐的直觉: 我们将每一列中不选哪种颜色看作是一个序列, 则我们发现这个序列要求相邻两位的颜色不同. 我们还发现, 一个这样的序列对应两种不同的合法的棋盘, 因此统计合法 ...
- NOI模拟题4 Problem A: 生成树(mst)
Solution 我们考虑答案的表达式: \[ ans = \sqrt{\frac{\sum_{i = 1}^{n - 1} (w_i - \overline{w})^2}{n - 1}} \] 其中 ...
- 花海漫步 NOI模拟题
题目好像难以看懂? 题目大意 给出一个字符串\(S\),统计满足以下条件的\((i,j,p,q)\)的数量. \(i \leq j, p \leq q\) \(S[i..j],S[p..q]\)是回文 ...
- 神奇的矩阵 NOI模拟题
神奇的矩阵 题目大意 有一个矩阵\(A\),第一行是给出的,接下来第\(x\)行,第\(y\)个元素的值为数字\(A_{x-1,y}\)在\(\{A_{x-1,1},A_{x-1,2},A_{x-1, ...
- Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem K. UTF-8 Decoder 模拟题
Problem K. UTF-8 Decoder 题目连接: http://opentrains.snarknews.info/~ejudge/team.cgi?SID=c75360ed7f2c702 ...
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem I. Interest Targeting 模拟题
Problem I. Interest Targeting 题目连接: http://codeforces.com/gym/100714 Description A unique display ad ...
随机推荐
- 使用WMI Filter 实现组策略的筛选!
今天接到一个客户的一个问题,提到需要分系统版本分发相应的MSI程序.比如简体版接受简体版的分发程序,繁体版接受繁体版的分发程序!这个建立组策略的不同版本分发本身不会太难,我们只需要建立两个不同组策略分 ...
- Python框架之Django学习笔记(十七)
Django框架之表单(续二) 今天的这篇博客将是Django学习笔记博客的最后一篇,基本每周最少一篇的Django框架学习,坚持到今天也实属不易,当然了,这个框架的学习仅仅是Django框架的基础部 ...
- live 555 freebsd 或centos 7.4 实现代理视频直播服务
live 555 freebsd 或centos 7.4 实现代理视频直播服务 the live555 media server 在线直播服务器 关于此服务器 此服务是一个无安全的rtsp服 ...
- [python工具][pycharm]pycharm licence activation失效的解决方法
推荐网站: http://idea.lanyus.com/ 1 请将“0.0.0.0 account.jetbrains.com”添加到C:\Windows\System32\Drivers\etc\ ...
- sun.misc.BASE64Encoder()编码有换行符需要手动去除passwordEncode.replace("\n","");
String passwordEncode = new BASE64Encoder().encodeBuffer(password.getBytes());//sun.misc.BASE64Encod ...
- ansible中playbook使用
palybook使用 ####yaml语法ansible中使用的yaml基础元素:变量Inventory条件测试迭代 playbook的组成结构InventoryModulesAd Hoc Comma ...
- java连接mysql数据库 三 实现增删改查操作
同以前一样,先写一个数据库打开和关闭操作类 public class DBConnection { String driver = "com.mysql.jdbc.Driver"; ...
- [kuangbin带你飞]专题十一 网络流个人题解(L题留坑)
A - ACM Computer Factory 题目描述:某个工厂可以利用P个部件做一台电脑,有N个加工用的机器,但是每一个机器需要特定的部分才能加工,给你P与N,然后是N行描述机器的最大同时加工数 ...
- ionic2 使用slides制作滑动效果的类型选择栏
类似的效果如下图: 1. 生成一个component ionic g component MySlide 2. 在my-slide.html中添加代码: <ion-slides class=&q ...
- Gym 100989F 水&愚&vector
standard input/output You must have heard about Agent Mahone! Dr. Ibrahim hired him to catch the che ...