题意就不说了。

分析:折腾好几天自己写的代码还是看了别人代码后发现几乎没什么复杂度的差别,可是就是一直超时,后来干脆照着别人写啊,一直WA,就在准备放弃干脆先写这篇博客的时候,又看了一眼WA的代码,发现一个中间变量没有取模直接爆掉了。终于AC了,做了好几天。

思路:对所有单词建立AC自动机,那么每个节点j转移到下一个节点k有方程:dp[i+1][k] =sum{dp[i][j]*Get},表示第i+1步位于k节点,并且由j节点转移过来,其中 Get =  ∏prime[i]*(len[i]+j)。 关键在于这里,结果是要对  179*173*163 取模, 而且Get函数和j有关,也就是走到了第j步,可以先将结果对179, 173, 163取模,然后利用中国剩余定理求出最终结果。

中国剩余定理,可以利用扩展欧几里得求出。我还是不知道我超时的原因,真是给跪了!!!!

别人代码也差不多4000+ms,我写的可能更搓了。

代码:

 #pragma comment(linker, "/STACK:16777216")
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#define inf 0x0f0f0f0f
#define in freopen("data.txt", "r", stdin);
#define pb push_back using namespace std;
typedef long long LL; const int maxnode = ;
const int sigma_size = ;
int prime[maxnode], vis[]; void getPrime() {
int cnt = ;
for(int i = ; i < && cnt <= ; i++) {
if(!vis[i]) prime[++cnt] = i;
for(int j = i*i; j < ; j += i)
vis[j] = ;
}
} struct Node {
int len, n;
Node(int len, int n): len(len), n(n) {}
};
int ch[maxnode][sigma_size], sz, f[maxnode]; vector<Node> vec[maxnode];
struct Matrix {
int a[][];
} xx[], E0;;
void maMul(Matrix x, Matrix y, Matrix &res, int mod) {
for(int i = ; i < sz; i++)
for(int j = ; j < sz; j++) {
res.a[i][j] = ;
for(int k = ; k < sz; k++) {
res.a[i][j] += x.a[i][k]*y.a[k][j]%mod;
if(res.a[i][j] >= mod)
res.a[i][j] -= mod;
}
}
}
struct AC { void init() {
sz = ;
memset(ch[], , sizeof ch[]);
vec[].clear();
}
int idx(char ch) {
return ch - 'A';
}
void insert(char *s, int x) {
int u = , len = ;
for(int i = ; s[i]; i++, len++) {
int c = idx(s[i]);
if(!ch[u][c]) {
memset(ch[sz], , sizeof ch[sz]);
vec[sz].clear();
ch[u][c] = sz++;
}
u = ch[u][c];
}
vec[u].pb(Node(len, prime[x]));
}
void getFail() {
queue<int> q;
f[] = ;
for(int c = ; c < sigma_size; c++) {
int u = ch[][c];
if(u) {
f[u] = ;
q.push(u);
}
}
while(!q.empty()) {
int r = q.front();
q.pop();
for(int c = ; c < sigma_size; c++) {
int u = ch[r][c];
if(!u) {
ch[r][c] = ch[f[r]][c];
continue;
}
q.push(u);
int v = f[r];
while(v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
}
}
}
void getMat(int x, int mod) {
for(int i = ; i < sz; i++) for(int j = ; j < sz; j++) xx[x].a[i][j] = ;
for(int u = ; u < sz; u ++)
for(int c = ; c < sigma_size; c++) {
int v = ch[u][c];
int tv = v;
int res = ;
while(tv) {
for(int i = ; i < (int)vec[tv].size(); i++) {
(res *= ((LL)(vec[tv][i].len+x)*vec[tv][i].n%mod))%=mod;
}
tv = f[tv];
}
xx[x].a[v][u] += res;
if(xx[x].a[v][u] >= mod) xx[x].a[v][u] -= mod;
}
}
} solver; int N;
LL L;
int M[] = {, , };
int ans[], a[];
int exgcd(int a, int b, int &x, int &y) {
if(!b) {
x = , y = ;
return a;
} else {
int tmp = exgcd(b, a%b, y, x);
y -= (a/b)*x;
return tmp;
}
}
void powmod(Matrix x, LL n, Matrix &res, int mod) {
res = E0;
while(n) {
if(n&) maMul(res, x, res, mod);
maMul(x, x, x, mod);
n >>= ;
}
}
int solve() { solver.getFail();
int mul = , res = ; for(int i = ; i < ; i++) mul *= M[i];
for(int i = ; i < ; i++) {
a[i] = mul/M[i];
Matrix tmp1, tmp2;
tmp1 = tmp2 = E0;
LL lv = L%M[i];
for(int k = M[i]; k >= ; k--) {
solver.getMat(k, M[i]);
maMul(tmp1, xx[k], tmp1, M[i]);
if(k <= lv)
maMul(tmp2, xx[k], tmp2, M[i]);
}
powmod(tmp1, L/M[i], tmp1, M[i]);
maMul(tmp2, tmp1, tmp1, M[i]);
ans[i] = ;
for(int k = ; k < sz; k++) {
ans[i] += tmp1.a[k][];
if(ans[i] >= M[i]) ans[i] -= M[i];
}
int xx, yy;
exgcd(a[i], M[i], xx, yy);
res += a[i]*ans[i]%mul*(xx%M[i])%mul;
if(res >= mul)
res -= mul;
}
return (res+mul)%mul;
}
int main() { getPrime();
int kase = ; for(int i = ; i < ; i++) for(int j = ; j < ; j++) E0.a[i][j] = i == j; while(scanf("%d%I64d", &N, &L) == ) {
solver.init();
for(int i = ; i <= N; i++) {
char s[];
scanf("%s", s);
solver.insert(s, i);
}
// printf("%d\n", sz);
printf("Case #%d: %d\n", ++kase, solve());
}
return ;
}

hdu 4878 ZCC loves words AC自动机+中国剩余定理+快速幂的更多相关文章

  1. 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂

    [题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望 ...

  2. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂

    [题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...

  3. Luogu-3250 [BJOI2017]魔法咒语(AC自动机,矩阵快速幂)

    Luogu-3250 [BJOI2017]魔法咒语(AC自动机,矩阵快速幂) 题目链接 题解: 多串匹配问题,很容易想到是AC自动机 先构建忌讳词语的AC自动机,构建时顺便记录一下这个点以及它的所有后 ...

  4. [poj2778 DNA Sequence]AC自动机,矩阵快速幂

    题意:给一些字符串的集合S和整数n,求满足 长度为n 只含charset = {'A'.'T‘.'G'.'C'}包含的字符 不包含S中任一字符串 的字符串的种类数. 思路:首先对S建立ac自动机,考虑 ...

  5. BZOJ2553 Beijing2011禁忌(AC自动机+动态规划+矩阵快速幂+概率期望)

    考虑对一个串如何分割能取得最大值.那么这是一个经典的线段覆盖问题,显然每次取右端点尽量靠前的串.于是可以把串放在AC自动机上跑,找到一个合法串后就记录并跳到根. 然后考虑dp.设f[i][j]表示前i ...

  6. BZOJ1951 [Sdoi2010]古代猪文 中国剩余定理 快速幂 数论

    原文链接http://www.cnblogs.com/zhouzhendong/p/8109156.html 题目传送门 - BZOJ1951 题意概括 求 GM mod 999911659 M=∑i ...

  7. HDU 4876 ZCC loves cards(暴力剪枝)

    HDU 4876 ZCC loves cards 题目链接 题意:给定一些卡片,每一个卡片上有数字,如今选k个卡片,绕成一个环,每次能够再这个环上连续选1 - k张卡片,得到他们的异或和的数,给定一个 ...

  8. hdu 4873 ZCC Loves Intersection(大数+概率)

    pid=4873" target="_blank" style="">题目链接:hdu 4873 ZCC Loves Intersection ...

  9. hdu 4876 ZCC loves cards(暴力)

    题目链接:hdu 4876 ZCC loves cards 题目大意:给出n,k,l,表示有n张牌,每张牌有值.选取当中k张排列成圈,然后在该圈上进行游戏,每次选取m(1≤m≤k)张连续的牌,取牌上值 ...

随机推荐

  1. files_dir

    一.opendir() —— 打开目录 opendir( 打开的当前目录 );   二.closedir() —— 关闭目录   三.readdir() —— 返回目录中的各个元素,返回上一个并且指向 ...

  2. BFC引发的关于position的思考

    BFC布局规则: 内部的Box会在垂直方向,一个接一个地放置. Box垂直方向的距离由margin决定.属于同一个BFC的两个相邻Box的margin会发生重叠 每个元素的margin box的左边, ...

  3. scala学习笔记:match表达式

    写了一个超级长的表达式,估计不是最简洁的: scala> def foo(ch:Any)=ch match { case true=>"male";case false ...

  4. Microsoft Visual Studio 2013 Update 1 离线安装程序

    ☆ 微软官网地址:☆http://www.microsoft.com/zh-cn/download/details.aspx?id=41650☆ 离线安装程序 直接下载链接:☆http://downl ...

  5. AppWidgetProvider生命周期

    1.在桌面上添加小部件,让小部件可用会调用:onEnabled 2.作为通知会调用onReceive 3.小部件可用后会调用onUpdate,表明小部件状态由不可用变为可用发生了变化 4.作为通知又会 ...

  6. 关于windows10调试应用注册失败

    搜索了一些方法,都是win8系统的应用程序解决方案,修改应用程序的包名.也尝试修改了一些,但是失败,任然报错,以前在这个机器上面是能正常调试的,唯一的不同点是就是系统升级到10166了,于是去设置里面 ...

  7. ECMAScript布尔操作符

    在ECMAScript中提供了Boolean()转换函数以及三个布尔操作符,这三个布尔操作符分别为逻辑非.逻辑与.逻辑或,这三个操作符通常用作于某些值的求反,比较模式等.学好这一点知识也非常的重要,奠 ...

  8. PC软件-实用工具 True Launch Bar

    True Launch Bar 官网 增强及自定义window任务栏快捷方式管理. 有免费版的Free Launch Bar 官网

  9. 让hyper-v调整console的大小

    在hyper-v中centos的console一直都是1024x768的分辨率,后来找到一种修改分辨率的解决方法 grubby --update-kernel=ALL --args="vid ...

  10. tar解压去除文件夹

    tar zxvf test.tar.gz  --strip-components 1 解压到当前目录,并去除一级目录