Solution

考虑分开统计朝向每一个方向的所有狐狸对答案的贡献. 比如说以向右为例, 我们用箭标表示每一只狐狸的方向, 用\('\)表示当前一步移动之前的每一只狐狸的位置.

\[\begin{aligned}
\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的优化除了常见的斜率/优先队列外, 不要忘了还有矩乘可用.

  1. #include <cstdio>
  2. #include <cstring>
  3. const long long mv[4][2] = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
  4. const long long MOD = 1e9 + 7;
  5. struct matrix
  6. {
  7. long long a[16][16];
  8. inline void build(long long S, long long L, long long R)
  9. {
  10. memset(a, 0, sizeof(a));
  11. for (long long i = 0; i < 4; ++ i)
  12. {
  13. for (long long j = 0; j < 4; ++ j)
  14. a[4 * i | j][4 * i | j] += S,
  15. a[4 * i | j][4 * ((i - 1 + 4) % 4) | j] += R,
  16. a[4 * i | j][4 * ((i + 1 + 4) % 4) | j] += L;
  17. for (long long j = 0; j < 2; ++ j)
  18. a[4 * i | j][4 * i | 2] = (a[4 * i | j][4 * i | 2] + S * mv[i][j] + MOD) % MOD,
  19. a[4 * i | 3][4 * i | j] = (a[4 * i | 3][4 * i | j] + S * mv[i][! j] + MOD) % MOD;
  20. }
  21. /* for (long long i = 0; i < 16; ++ i)
  22. {
  23. for(long long j = 0; j < 16; ++ j) prlong longf("%d ", a[i][j]);
  24. puts("");
  25. } */
  26. }
  27. inline matrix friend operator *(matrix a, matrix b)
  28. {
  29. matrix res; memset(res.a, 0, sizeof res.a);
  30. for (long long i = 0; i < 16; ++ i) for (long long j = 0; j < 16; ++ j) for (long long k = 0; k < 16; ++ k)
  31. res.a[i][j] = (res.a[i][j] + a.a[i][k] * b.a[k][j] % MOD) % MOD;
  32. return res;
  33. }
  34. }trans, a;
  35. inline matrix power(long long x)
  36. {
  37. matrix res; memset(res.a, 0, sizeof res.a);
  38. for (long long i = 0; i < 16; ++ i) res.a[i][i] = 1;
  39. for (; x; trans = trans * trans, x >>= 1)
  40. if (x & 1) res = res * trans;
  41. return res;
  42. }
  43. int main()
  44. {
  45. #ifndef ONLINE_JUDGE
  46. freopen("fox.in", "r", stdin);
  47. freopen("fox.out", "w", stdout);
  48. #endif
  49. long long T; scanf("%d", &T);
  50. for(long long cs = 0; cs < T; ++ cs)
  51. {
  52. long long t, S, L, R; scanf("%lld%lld%lld%lld", &t, &S, &L, &R);
  53. trans.build(S, L, R);
  54. matrix res = power(t);
  55. long long ans = 0;
  56. for (long long i = 3; i < 16; i += 4) ans = (ans + res.a[i][2]) % MOD;
  57. printf("%d\n", ans);
  58. }
  59. }

NOI模拟题4 Problem B: 小狐狸(fox)的更多相关文章

  1. 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 ...

  2. NOI模拟题6 Problem C: Circle

    Solution 首先这个矩阵, 很明显的就是Vandermonde矩阵. 我们有公式: \[ |F_n| = \prod_{1 \le j < i \le n} (a_i - a_j) \] ...

  3. NOI模拟题5 Problem A: 开场题

    Solution 注意到\(\gcd\)具有结合律: \[ \gcd(a, b, c) = \gcd(a, \gcd(b, c)) \] 因此我们从后往前, 对于每个位置\(L\), 找到每一段不同的 ...

  4. NOI模拟题4 Problem C: 填格子(board)

    Solution 首先我们要有敏锐的直觉: 我们将每一列中不选哪种颜色看作是一个序列, 则我们发现这个序列要求相邻两位的颜色不同. 我们还发现, 一个这样的序列对应两种不同的合法的棋盘, 因此统计合法 ...

  5. NOI模拟题4 Problem A: 生成树(mst)

    Solution 我们考虑答案的表达式: \[ ans = \sqrt{\frac{\sum_{i = 1}^{n - 1} (w_i - \overline{w})^2}{n - 1}} \] 其中 ...

  6. 花海漫步 NOI模拟题

    题目好像难以看懂? 题目大意 给出一个字符串\(S\),统计满足以下条件的\((i,j,p,q)\)的数量. \(i \leq j, p \leq q\) \(S[i..j],S[p..q]\)是回文 ...

  7. 神奇的矩阵 NOI模拟题

    神奇的矩阵 题目大意 有一个矩阵\(A\),第一行是给出的,接下来第\(x\)行,第\(y\)个元素的值为数字\(A_{x-1,y}\)在\(\{A_{x-1,1},A_{x-1,2},A_{x-1, ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. 基类View

    尽管类视图看上去类的种类繁多,但每个类都是各司其职的,且从类的命名就可以很容易地看出这个类的功能.大致可分为如下三个大的功能块,分别由三个类提供对应的方法: 处理 HTTP 请求.根据 HTTP 请求 ...

  2. mysql基础查询

    #进阶1:基础查询/*语法:select:查询列表 from 表名; 类似于:System.out.println(打印的东西); 特点:1.查询列表可以是:表中的字段.常量值.表达式.函数2.查询的 ...

  3. 分治 - 计算几何 - BZOJ2458,[BeiJing2011]最小三角形

    http://www.lydsy.com/JudgeOnline/problem.php?id=2458 [BeiJing2011]最小三角形 描述 Frisk现在遇到了一个有趣的问题. 平面上有N个 ...

  4. Git之2分钟教程

    Git之2分钟入门 普通人:“借我1000块钱”.程序猿:“借你1024吧,凑个整”. 今天是1024,是我们程序员的节日,在此,首先祝各位程序猿以及程序媛们节日快乐~然后送出一份节日礼物,没错,就是 ...

  5. 移动弱网测试方案Network Emulator for Windows Toolkit

    移动app在测试时,有时需要考虑弱网的情形下,app的表现,那么怎么营造这样子的环境呢? 一.首先需要控制网络,有两种方式其一使用网络损伤仪进行,其二采用软件方式.硬件采购费用太贵,因此使用win平台 ...

  6. Mac Xnip 截图软件快捷键设置

    点击 Shortcut 后输入你需要的截图快捷键

  7. mysql数据库增、删、改、查等基本命令

    测试环境:windows7 64位 mysql.exe.Navicat Lite for MySQL.mysql 5.0.18 mysql数据库的基本结构: 数据库(database)包含多个表(ta ...

  8. 【homework #1】第一次作业被虐感受

    当大二暑假结束,我发现我还是没有熟练掌握一门编程语言时,我就知道苦日子要来了. 这不,才开学第三周,就已经被虐的体无完肤了.连编译课用C语言写的词法分析,都要写很久.Debug很久才能写出来,更别提大 ...

  9. input[type="radio"]自定义样式

    input为radio时,虽然会有默认选中的样式,但是并不符合大多数项目的需求,我们的目标是可以随心所欲自定义它的样式.怎么做呢?其实很简单,只要抓住3点.分别是1.label 2.隐藏自带样式 3. ...

  10. codevs 1690 开关灯 线段树区间更新 区间查询Lazy

    题目描述 Description YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人 ...