POJ 1625
什么鬼,真的是有负数的吗?我在字符加上了128才过了。dp[i][j],经过i步到达j状态的路径数。转移很容易了,建个trie图就可以,由前一步可连通到和更新即可。
另外,要用到大数和AC自动机DP
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <string.h>
#include <queue>
#include <cmath>
#include <map>
#include <vector>
#define LL __int64
using namespace std; const __int64 forward=100000000000000000LL;
const int root=;
const int Maxn=;
int idx[];
struct BigNumber{
LL num[];
void initial(){
for(int i=;i<;i++)
num[i]=;
}
};
BigNumber add_BigNumber(BigNumber a,BigNumber b){
BigNumber c;
c.initial();
for(int i=;i<;i++){
c.num[i]=c.num[i]+a.num[i]+b.num[i];
c.num[i+]=c.num[i]/forward;
c.num[i]%=forward;
}
return c;
}
BigNumber dp[][];
struct Node{
bool tag;
int next[];
int fail;
void initial(){
tag=false;
memset(next,-,sizeof(next));
fail=-;
}
};
int que[Maxn],head,tail,tot;
Node trie[Maxn];
int dictsize,step;
char str[]; void build_ac(){
head=tail=;
que[tail++]=root;
int tmp,p;
while(head!=tail){
tmp=que[head++];
p=-;
for(int i=;i<dictsize;i++){
if(trie[tmp].next[i]!=-){
if(tmp==root) trie[trie[tmp].next[i]].fail=root;
else{
p=trie[tmp].fail;
while(p!=-){
if(trie[p].next[i]!=-){
trie[trie[tmp].next[i]].fail=trie[p].next[i];
break;
}
p=trie[p].fail;
}
if(p==-) trie[trie[tmp].next[i]].fail=root;
}
if(trie[trie[trie[tmp].next[i]].fail].tag)
trie[trie[tmp].next[i]].tag=true;
que[tail++]=trie[tmp].next[i];
}
else{ //trie[tmp].next[i]==-1
if(tmp==root) trie[tmp].next[i]=root;
else{
p=trie[tmp].fail;
while(p!=-){
if(trie[p].next[i]!=-){
trie[tmp].next[i]=trie[p].next[i];
break;
}
p=trie[p].fail;
}
if(p==-) trie[tmp].next[i]=root;
}
}
}
}
} int main(){
int n,m,p,pt;
cin>>n>>m>>p;
for(int i=;i<Maxn;i++) trie[i].initial();
head=tail=tot=;
dictsize=n; step=m;
cin>>str;
for(int i=;i<n;i++)
idx[str[i]+]=i;
// cout<<idx['a']<<endl;
// cout<<idx['b']<<endl;
for(int i=;i<p;i++){
cin>>str;
pt=root;int k=;
int len=strlen(str);
while(k<len){
if(trie[pt].next[idx[str[k]+]]==-) trie[pt].next[idx[str[k]+]]=++tot;
pt=trie[pt].next[idx[str[k]+]];
k++;
}
trie[pt].tag=true;
}
// cout<<"YES"<<endl;
build_ac();
// cout<<"YEA"<<endl;
for(int i=;i<=tot;i++){
for(int j=;j<=step;j++)
dp[i][j].initial();
}
dp[][].num[]=;
for(int k=;k<step;k++){
for(int i=;i<=tot;i++){
if(!trie[i].tag){
for(int j=;j<dictsize;j++){
if(!trie[trie[i].next[j]].tag)
dp[trie[i].next[j]][k+]=add_BigNumber(dp[trie[i].next[j]][k+],dp[i][k]);
}
}
}
}
BigNumber ans;
ans.initial();
// cout<<tot<<endl;
for(int i=;i<=tot;i++){
if(!trie[i].tag){
ans=add_BigNumber(ans,dp[i][step]);
}
}
bool flag=false;
for(int i=;i>=;i--)
if(ans.num[i]>||flag){
if(flag)
printf("%017I64d",ans.num[i]);
else
printf("%I64d",ans.num[i]);
flag=true;
}
if(flag)
printf("%017I64d\n",ans.num[]);
else{
printf("%I64d\n",ans.num[]);
}
return ;
}
POJ 1625的更多相关文章
- POJ 1625 Censored!(AC自动机+高精度+dp)
http://poj.org/problem?id=1625 题意: 给出一些单词,求长度为m的串不包含这些单词的个数. 思路: 这道题和HDU 2243和POJ 2778是一样的,不同的是这道题不取 ...
- POJ 1625 Censored!(AC自动机+DP+高精度)
Censored! Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 6956 Accepted: 1887 Descrip ...
- POJ 1625 Censored ( Trie图 && DP && 高精度 )
题意 : 给出 n 个单词组成的字符集 以及 p 个非法串,问你用字符集里面的单词构造长度为 m 的单词的方案数有多少种? 分析 :先构造出 Trie 图方便进行状态转移,这与在 POJ 2278 中 ...
- Match:Censored!(AC自动机+DP+高精度)(POJ 1625)
Censored! 题目大意:给定一些字符,将这些字符组成一个固定长度的字符串,但是字符串不能包含一些禁词,问你有多少种组合方式. 这是一道好题,既然出现了“一些”禁词,那么这题肯定和AC自动机有点 ...
- POJ 1625 Censored!
辣鸡OI毁我青春 Description The alphabet of Freeland consists of exactly N letters. Each sentence of Freela ...
- poj 1625 (AC自动机好模版,大数好模版)
题目 给n个字母,构成长度为m的串,总共有n^m种.给p个字符串,问n^m种字符串中不包含(不是子串)这p个字符串的个数. 将p个不能包含的字符串建立AC自动机,每个结点用val值来标记以当前节点为后 ...
- POJ 1625 Censored!(大数+DP)
题目链接 这题,真心木啥意思,就是数据里貌似字符有负数,注意gets读入.. #include <iostream> #include <cstring> #include & ...
- Censored! - POJ 1625(ac自动机+简单dp+高精度运算)
题目大意:首先给一个字符集合,这个集合有N个字符,然后需要一个长度为M的句子,但是据子里面不能包含的串有P个,每个串里面的字符都是有字符集和里面的字符构成的,现在想知道最多能构造多少个不重复的句子. ...
- POJ 1625 Censored! [AC自动机 高精度]
Censored! Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 9793 Accepted: 2686 Descrip ...
- POJ 1625 Censored!(AC自动机->指针版+DP+大数)题解
题目:给你n个字母,p个模式串,要你写一个长度为m的串,要求这个串不能包含模式串,问你这样的串最多能写几个 思路:dp+AC自动机应该能看出来,万万没想到这题还要加大数...orz 状态转移方程dp[ ...
随机推荐
- 实现泛型IEnumerable接口
用C#实现一个类的IEnumerable接口时有两种方法:1)实现非泛型IEnumerable接口:2)实现泛型IEnumerable(T)接口.如果采用方法1,当集合元素T是值类型时,将涉及到巨多的 ...
- Apache上php项目简单部署
1.建一个简单的php项目 1)在目录C:\wamp\www中新建一个文件夹,命名为20151021 2)在文件夹20151021中新建一个index.php文件,内容为: <?php echo ...
- kafka参数在线修改
当kafka集群单个节点出现磁盘满了,需要清理历史topic数据:方法如下 1): 停掉kafka进程,将kafka的server.properties中的log.retention.hours=1/ ...
- mysql如何查询最新插入的数据
在MySQL中,使用auto_increment类型的id字段作为表的主键,并用它作为其他表的外键,形成“主从表结构”,这是数据库设计中常见的用法.但是在具体生成id的时候,我们的操作顺序一般是:先在 ...
- [Apple开发者帐户帮助]一、开始(2)登录您的开发者帐户
使用Apple ID登录您的开发者帐户.如果您注册了付费程序(Apple Developer Program或Apple Developer Enterprise Program),请使用您用于注册的 ...
- Python描述符:property()函数的小秘密
描述符:将某种特殊类型的类的实例指派给另一个类的属性(注意:这里是类属性,而不是对象属性).而这种特殊类型的类就是实现了__get__,__set__,__delete__这三个方法中的一个或多个的新 ...
- String和八种基本数据类型互相转换
//String转换为对应的八种基本数据类型 String str="100"; //Value out of range. Value:"200" Radix ...
- 重新理解 Monad
对于大多数刚刚入门函数式编程的同学来说,monad(单子.又叫单体)可能是这里面的一道坎.你可能对 map . flatMap 以及 filter 再熟悉不过,可是到了高阶的抽象层次上就又会变得一脸懵 ...
- Join 语句
select * from books as A join (select * from Orders) as B on A.BookId = B.BookId select A.BookId,Aut ...
- <转>c++引用与指针的区别(着重理解)
★ 相同点: 1. 都是地址的概念: 指针指向一块内存,它的内容是所指内存的地址:引用是某块内存的别名. ★ 区别: 1. 指针是一个实体,而引用仅是个别名: 2. 引用使用时无需解引用(*),指 ...