博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【bzoj5082】弗拉格 矩阵乘法
阅读量:4338 次
发布时间:2019-06-07

本文共 1794 字,大约阅读时间需要 5 分钟。

题目描述

给你n个flag,你要把每个染色成红黑白黄四色之一,满足:
1.相邻旗不能同色
2.白不能和黄相邻,红不能和黑相邻
3.不能存在连续三个球依次是“黑白红”或“红白黑”
4.翻转后相等视为等价
设不等价方案数为f(n),给定l,r,求
Sigma f(i),其中L<=i<=R模1000000007

输入

输入两个数l,r
l, r ≤ 10^9

输出

输出答案

样例输入

3 4

样例输出

23


题解

矩阵乘法

容易设出dp状态 $f[i][j][k]$ 表示前 $i$ 个flag,最后一个的颜色为 $j$ ,倒数第二个的颜色为 $k$ 的方案数。

显然这个dp方程可以使用矩阵乘法来加速转移,并使用计数器维护前缀和。

至于翻转后相等视为等价的问题,易知:答案=(总方案数+翻转后与原来相等的方案数)/2。于是求出反转后与原来相等的方案数即可。

容易发现偶数长度的中间两个一定相同,因此不存在偶数长度的回文串。

对于奇数长度,发现题目条件的限制是对称的(AB<=>BA,ABC<=>CBA),因此某长度为 $2k-1$ 的奇数长度回文串的个数即为长度为 $k$ 的串的个数。再次求 $\lceil\frac n2\rceil$ 的答案即可。

最后前缀相减即为最终答案。

时间复杂度 $O(9^3\log n)$

#include 
#include
#include
#define mod 1000000007using namespace std;typedef long long ll;struct data{ ll v[9][9]; data() {memset(v , 0 , sizeof(v));} ll *operator[](int a) {return v[a];} data operator*(data &a) { data ans; int i , j , k; for(i = 0 ; i <= 8 ; i ++ ) for(j = 0 ; j <= 8 ; j ++ ) for(k = 0 ; k <= 8 ; k ++ ) ans[i][j] = (ans[i][j] + v[i][k] * a[k][j]) % mod; return ans; }}A;data pow(data x , int y){ data ans; int i; for(i = 0 ; i <= 8 ; i ++ ) ans[i][i] = 1; while(y) { if(y & 1) ans = ans * x; x = x * x , y >>= 1; } return ans;}void init(){ int i; for(i = 0 ; i <= 8 ; i ++ ) A[i][0] = 1; A[1][5] = A[1][7] = 1; A[2][5] = A[2][7] = 1; A[3][6] = A[3][8] = 1; A[4][6] = A[4][8] = 1; A[5][1] = A[5][3] = 1; A[6][1] = A[6][3] = 1; A[7][2] = 1; A[8][4] = 1;}ll calc(int x){ if(!x) return 0; data T = pow(A , x - 1); ll ans = T[0][0] * 4; int i; for(i = 1 ; i <= 8 ; i ++ ) ans += T[i][0]; return ans % mod;}int main(){ int l , r; scanf("%d%d" , &l , &r) , l -- ; init(); printf("%lld\n" , ((calc(r) + calc((r + 1) / 2) - calc(l) - calc((l + 1) / 2)) * 500000004 % mod + mod) % mod); return 0;}

 

转载于:https://www.cnblogs.com/GXZlegend/p/7886580.html

你可能感兴趣的文章
使用正确的姿势跨域
查看>>
AccountManager教程
查看>>
Android学习笔记(十一)——从意图返回结果
查看>>
算法导论笔记(四)算法分析常用符号
查看>>
ultraedit激活
查看>>
总结(6)--- python基础知识点小结(细全)
查看>>
亿级曝光品牌视频的幕后设定
查看>>
ARPA
查看>>
JSP开发模式
查看>>
我的Android进阶之旅------&gt;Android嵌入图像InsetDrawable的使用方法
查看>>
Detours信息泄漏漏洞
查看>>
win32使用拖放文件
查看>>
Android 动态显示和隐藏软键盘
查看>>
raid5什么意思?怎样做raid5?raid5 几块硬盘?
查看>>
【转】how can i build fast
查看>>
null?对象?异常?到底应该如何返回错误信息
查看>>
django登录验证码操作
查看>>
(简单)华为Nova青春 WAS-AL00的USB调试模式在哪里开启的流程
查看>>
图论知识,博客
查看>>
[原创]一篇无关技术的小日记(仅作暂存)
查看>>