题目链接

洛谷P4608

题解

建个序列自动机后

第一问暴搜

第二问dp + 高精

设\(f[i][j]\)为两个序列自动机分别走到\(i\)和\(j\)节点的方案数,答案就是\(f[0][0]\)

由于空间卡的很紧,高精不仅要压位,还要动态开内存

由于有些状态是没用的,记忆化搜索以减少内存损失

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 3015,P = 1000000000,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
char X[maxn],Y[maxn];
int typ,n,m,last[60];
inline int id(char c){return c >= 'a' ? 26 + c - 'a' : c - 'A';}
struct LAM{
int ch[maxn][52],cnt;
void build(char* S,int len){
for (int i = 0; i < 52; i++) last[i] = 0;
cnt = len;
for (int i = len; i; i--){
for (int j = 0; j < 52; j++)
ch[i][j] = last[j];
last[id(S[i])] = i;
}
for (int i = 0; i < 52; i++) ch[0][i] = last[i];
}
}A,B;
char s[maxn];
int len,ans;
void dfs(int u,int v){
ans++;
for (int i = 1; i <= len; i++) putchar(s[i]); puts("");
for (int i = 0; i < 52; i++)
if (A.ch[u][i] && B.ch[v][i]){
s[++len] = i > 25 ? 'a' + i - 26 : 'A' + i;
dfs(A.ch[u][i],B.ch[v][i]);
len--;
}
}
void work1(){
dfs(0,0);
printf("%d\n",ans);
};
struct NUM{
int len;
LL* s;
void init(){
s = new LL[20];
for (int i = 0; i < 20; i++) s[i] = 0;
len = 0;
}
void out(){
if (!len){puts("0"); return;}
printf("%lld",s[len - 1]);
for (int i = len - 2; ~i; i--)
printf("%09lld",s[i]);
}
void add(const NUM& a){
LL carry = 0,tmp,L = max(len,a.len);
for (int i = 0; i < L; i++){
tmp = s[i] + a.s[i] + carry;
s[i] = tmp % P;
carry = tmp / P;
}
if (carry) s[L] += carry;
len = 0;
for (int i = 19; ~i; i--) if (s[i]){len = i + 1; break;}
}
}f[maxn][maxn];
int vis[maxn][maxn];
void DFS(int u,int v){
if (vis[u][v]) return;
vis[u][v] = true;
f[u][v].init();
f[u][v].s[0] = f[u][v].len = 1;
for (int i = 0; i < 52; i++)
if (A.ch[u][i] && B.ch[v][i]){
DFS(A.ch[u][i],B.ch[v][i]);
f[u][v].add(f[A.ch[u][i]][B.ch[v][i]]);
}
}
void work2(){
DFS(0,0);
f[0][0].out();
}
int main(){
n = read(); m = read();
scanf("%s%s%d",X + 1,Y + 1,&typ);
A.build(X,n); B.build(Y,m);
if (typ) work1();
else work2();
return 0;
}

洛谷P4608 [FJOI2016]所有公共子序列问题 【序列自动机 + dp + 高精】的更多相关文章

  1. 洛谷P3402 最长公共子序列

    题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作 ...

  2. 洛谷P1439 最长公共子序列(LCS问题)

    题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子 ...

  3. 洛谷 [p1439] 最长公共子序列 (NlogN)

    可以发现只有当两个序列中都没有重复元素时(1-n的排列)此种优化才是高效的,不然可能很不稳定. 求a[] 与b[]中的LCS 通过记录lis[i]表示a[i]在b[]中的位置,将LCS问题转化为最长上 ...

  4. LOJ 2172 「FJOI2016」所有公共子序列问题——序列自动机

    题目:https://loj.ac/problem/2172 在两个序列自动机上同时走,这样暴搜. 先走字典序小的字符,一边搜一边输出,就是按字典序排序的. 方案数很多,需要高精度?空间很小,要压位. ...

  5. 洛谷P4762 [CERC2014]Virus synthesis(回文自动机+dp)

    传送门 回文自动机的好题啊 先建一个回文自动机,然后记$dp[i]$表示转移到$i$节点代表的回文串的最少的需要次数 首先肯定2操作越多越好,经过2操作之后的串必定是一个回文串,所以最后的答案肯定是由 ...

  6. 序列自动机—— [FJOI2016]所有公共子序列问题

    序列自动机: 是一个处理子序列的自动机.就这样. 建造:(By猫老师:immoralCO猫) s[] next[][] memset(next[n], -, <<); for(int i ...

  7. 洛谷CF264D Colorful Stones(子序列匹配,思维)

    洛谷题目传送门 神仙思维题. 对于两个字符串的匹配问题,似乎之前蒟蒻写的HAOI2010最长公共子序列题解中提到的建网格图模型是一种套路? 给一个稍微强一点的样例(把字母换成了ABC) AABCB B ...

  8. [洛谷P4609] [FJOI2016]建筑师

    洛谷题目链接:[FJOI2016]建筑师 题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 \(n\) 个建筑,每个建筑的高度是 \(1\) 到 \(n\) 之间的一 ...

  9. 洛谷 P4609: [FJOI2016] 建筑师

    本省省选题是需要做的. 题目传送门:洛谷P4609. 题意简述: 求有多少个 \(1\) 到 \(N\) 的排列,满足比之前的所有数都大的数正好有 \(A\) 个,比之后的所有数都大的数正好有 \(B ...

随机推荐

  1. shell 参数

    转:http://hi.baidu.com/ipvsadm/item/489d9e16460195ddbe9042ee linux中shell变量$#,$@,$0,$1,$2的含义解释 linux中s ...

  2. mysql增删改查、连表查询、常用操作

    一.建表 1.最简单的建表CREATE TABLE user(id int,name char(20),age int); 2.带主键带注释和默认值创建表CREATE TABLE  user(id I ...

  3. 心中忐忑的跨进了Python的大门!

    Hello!大家好,我是Jmmy 作为一个python初学者,抱着一种忐忑的心里走进了这扇让我有些胆怯的大门,因为零基础的缘故让我不得不再三去考虑学这门语言,英语.数学都是个渣的我,也许注定会止步门外 ...

  4. Python基础入门(模块和包)

    1 模块 1.1 什么是模块 在 Python 中,一个 .py 文件就称之为一个模块(Module). 我们学习过函数,知道函数是实现一项或多项功能的一段程序 .其实模块就是函数功能的扩展.为什么这 ...

  5. Spark配置参数的三种方式

    1.Spark 属性Spark应用程序的运行是通过外部参数来控制的,参数的设置正确与否,好与坏会直接影响应用程序的性能,也就影响我们整个集群的性能.参数控制有以下方式:(1)直接设置在SparkCon ...

  6. Python 日志记录与程序流追踪(基础篇)

    日志记录(Logging) More than print: 每次用 terminal debug 时都要手动在各种可能出现 bug 的地方 print 相关信息来确认 bug 的位置: 每次完成 d ...

  7. DeepLearning - Regularization

    I have finished the first course in the DeepLearnin.ai series. The assignment is relatively easy, bu ...

  8. Ubuntu系统下在PyCharm里用virtualenv集成TensorFlow

    我的系统环境 Ubuntu 18.04 Python3.6 PyCharm 2018.3.2 community(免费版) Java 1.8 安装前准备 由于众所周知的原因,安装中需要下载大量包,尽量 ...

  9. eBay报告:德国或将成为外贸电商热门市场

    [亿邦动力网讯]1月3日消息,日前,跨境电商平台eBay发布公告称,自2014年1月中旬起,卖家在eBay德国 ( eBay.de ).eBay 奥地利 ( eBay.at ) 或eBay瑞士 ( e ...

  10. LeetCode 206. Reverse Linked List(C++)

    题目: Reverse a singly linked list. Example: Input: 1->2->3->4->5->NULL Output: 5->4 ...