传送门:>Here<

题意:现在有一长度为N的字符串,满足一下条件:

  (1) 字符串仅由A,B,C,D四个字母组成;
  (2) A出现偶数次(也可以不出现);
  (3) C出现偶数次(也可以不出现);
   计算满足条件的字符串个数.

解题思路

先解普通递推,然后矩阵乘法优化即可。一维好像没有什么好的解法……

$f[i][0]$表示长度为$i$的合法字符串的数量,$f[i][1]$表示仅A的个数为奇数的字符串数量,$f[i][2]$表示仅C的个数为奇数的字符串数量,$f[i][3]$表示A, C个数都为奇数的字符串数量

因此可得递推方程$$f[i][0] = f[i-1][0]*2 + f[i-1][1] + f[i-1][2]$$

这个方程的意义在于:考虑第$i$位相比已知的前$i-1$位加入什么。如果加入B或D,那么前面的必须合法。如果加入A或C,那么相应的前面的A或C的数量应当为奇数

问题一:为什么只考虑最后一位,当前这一位理论上不是插入前面的i-1个位置都可以吗?然而在这里是要考虑重复的,例如串$\{ AAB\}$,在最后一位或是倒数第二位插入B都将会得到$\{ AABB \}$。那前面的几位呢?如果在第二位插入,就变成了$\{ ABAB \}$,而这等同于在$\{ ABA \}$的后面插入了$B$,将归属于另一种情况。如果讨论了它,就会与别的情况有重复。总结起来,最后得到的串是不分插入位置的,不同的插入顺序得到的是同一个串。换句话说也就是所有B都是一样的。

问题二:为什么转移$f[i][0]$时不加上$f[i-2][3]$呢?试想倘若$f[i-2][3]$的末尾加上一个A,那么就会变成$f[i-1][2]$;加上C就会变成$f[i-1][1]$。而这两类都讨论过了,再讨论就重复了。

其他的几个的转移方法类似,最后我们得到转移方程组:$$\left\{\begin{matrix}f[i][0] = f[i-1][0]*2+f[i-1][1]+f[i-1][2]\\ f[i][1] = f[i-1][1]*2+f[i-1][0]+f[i-1][3]\\ f[i][2] = f[i-1][2]*2+f[i-1][0]+f[i-1][3]\\ f[i][3] = f[i-1][3]*2+f[i-1][1]+f[i-1][2]\\ \end{matrix}\right.$$

  因此可以推得矩阵$$ \begin{bmatrix} 2 & 1 & 1 & 0 \\ 1 & 2 & 0 & 1 \\ 1 & 0 & 2 & 1 \\ 0 & 1 & 1 & 2\end{bmatrix} $$

Code

不知道为什么反正要开longlong

/*By DennyQi*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
#define int long long
const int MAXN = ;
const int MAXM = ;
const int INF = ;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x << ) + (x << ) + c - '', c = getchar(); return x * w;
}
int T,N;
int a[][],b[][],ans[][];
inline void Matrix_KSM(int y){
while(y > ){
if(y & ){
for(int i = ; i <= ; ++i){
for(int j = ; j <= ; ++j){
b[i][j] = ;
for(int k = ; k <= ; ++k){
b[i][j] = (b[i][j] + ans[i][k] * a[k][j]) % ;
}
}
}
for(int i = ; i <= ; ++i){
for(int j = ; j <= ; ++j){
ans[i][j] = b[i][j];
}
}
}
for(int i = ; i <= ; ++i){
for(int j = ; j <= ; ++j){
b[i][j] = ;
for(int k = ; k <= ; ++k){
b[i][j] = (b[i][j] + a[i][k] * a[k][j]) % ;
}
}
}
for(int i = ; i <= ; ++i){
for(int j = ; j <= ; ++j){
a[i][j] = b[i][j];
}
}
y /= ;
}
}
inline void Solve(){
memset(ans,,sizeof(ans));
memset(a,,sizeof(a));
for(int i = ; i <= ; ++i) ans[i][i] = ;
a[][] = , a[][] = , a[][] = , a[][] = ;
a[][] = , a[][] = , a[][] = , a[][] = ;
a[][] = , a[][] = , a[][] = , a[][] = ;
a[][] = , a[][] = , a[][] = , a[][] = ;
Matrix_KSM(N-);
printf("%lld\n", (*ans[][]% + ans[][]% + ans[][]) % );
}
#undef int
int main(){
#define int long long
for(;;){
T = r;
if(!T) break;
for(int i = ; i <= T; ++i){
N = r;
printf("Case %lld: ",i);
Solve();
}
puts("");
}
return ;
}

[HDU2065] "红色病毒"问题的更多相关文章

  1. HDU2065 "红色病毒"问题 【组合数学 二项式定理】

    HDU2065 "红色病毒"问题 Description: 医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色 ...

  2. hdu2065"红色病毒"问题(指数母函数+快速幂取模)

    "红色病毒"问题 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  3. HDU2065"红色病毒"问题【指数型母函数】

    Problem Description 医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色病毒",经研究发现,该病毒及其 ...

  4. HDU2065 “红色病毒”问题 (指数型母函数经典板题)

    题面 医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色病毒",经研究发现,该病毒及其变种的DNA的一条单链中,胞嘧啶, ...

  5. hdu2065 "红色病毒"问题 指数型母函数

    关于指数型母函数的题目,通过用公式并展开得到系数做的吧,取最后两位就是对100取模 #include<stdio.h> int QuickPow(int a,long long n,int ...

  6. 【指数型母函数+非递归快速幂】【HDU2065】"红色病毒"问题

    大一上学完数分上后终于可以搞懂指数型母函数了.. 需要一点关于泰勒级数的高数知识 题目在此: "红色病毒"问题 Time Limit: 1000/1000 MS (Java/Oth ...

  7. HDUOJ-----2065"红色病毒"问题

    "红色病毒"问题 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  8. HDU 2065 "红色病毒"问题(生成函数)

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  9. HDU 2065 “红色病毒”问题 --指数型母函数

    这种有限制的类棋盘着色问题一般可以用指数型母函数来解决,设Hn表示这样的着色数,首先H0=1,则Hn等于四个字母的(A,B,C,D)的多重集合的n排列数,其中每个字母的重数是无穷,且要求A,C出现的次 ...

随机推荐

  1. Centos 7安装RabbitMQ 3.7.8版本(单机版)-不使用RPM

    RabbitMQ是目前非常热门的消息中间件,凭借其高可靠.高扩展.高可用及丰富的功能特性:TTL.死信队列.延迟队列.优先级队列.消息持久化.镜像队列. 消息中间件是指利用高效可靠的消息传递机制进行与 ...

  2. Oracle记录表删除操作简单方法

    最近项目中Oracle库中一个表log_gpackage有数据丢失现象,但因为没有启用归档,所以CDC和Dataguard都无法使用.google一下,最简单的方法,增加触发器处理逻辑: ---创建触 ...

  3. VMware(威睿)后端开发笔试题总结

    1.   Linux中查看系统的发行版本信息 的命令? cat/etc/issue    和    lsb_release 2.   linux 挂载一个共享文件夹: mount  -t  cifc ...

  4. Python-待

    内置函数总结 https://www.cnblogs.com/jason-lv/p/8243141.html https://www.cnblogs.com/pyyu/p/6702896.html 数 ...

  5. H5 65-清除浮动方式一

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Mike and palindrome CodeForces - 798A

    题目链接 一个简单的题目,但是却很少有人可以一次AC,比如我就瞎写wa了一次... 写本博算个教训录吧. 题目给出一个字符串,让你严格的改变一个字符使改变后的字符串是一个回文串. 回文串不用解释了.不 ...

  7. iOS保持App真后台运行

    https://www.jianshu.com/p/d466f2da0d33 在我看来,苹果系统与安卓系统最直观的区别就是后台处理方式了吧,安卓手机一旦开启了很多app放到后台,即使前台什么也不做,就 ...

  8. oracle事务的四个特性(ACID)

    事务产生的背景 当在PL/SQL中同时操作多个SQL语句,比如通过DML语句添加.修改或删除数据时,如何确保数据库数据不会因为意外而倒置错误数据是一个非常重要的问题. 以仓库发料系统为例,如果某一张领 ...

  9. 3 HTTP 协议

    1 什么是HTTP 协议 HTTP (HyperText Transfer Protocol),即超文本传输协议, 17年以前互联网上应用最广泛的协议,之后所有网站都开始使用HTTPS协议(基于HTT ...

  10. Mission Impossible 6

    题目:Mission Impossible 6 题目链接:http://hihocoder.com/problemset/problem/1228 题目大意: 大概就是让我们写一个代码模拟文本编辑器的 ...