洛谷P4608 [FJOI2016]所有公共子序列问题 【序列自动机 + dp + 高精】
题目链接
题解
建个序列自动机后
第一问暴搜
第二问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 + 高精】的更多相关文章
- 洛谷P3402 最长公共子序列
题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作 ...
- 洛谷P1439 最长公共子序列(LCS问题)
题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子 ...
- 洛谷 [p1439] 最长公共子序列 (NlogN)
可以发现只有当两个序列中都没有重复元素时(1-n的排列)此种优化才是高效的,不然可能很不稳定. 求a[] 与b[]中的LCS 通过记录lis[i]表示a[i]在b[]中的位置,将LCS问题转化为最长上 ...
- LOJ 2172 「FJOI2016」所有公共子序列问题——序列自动机
题目:https://loj.ac/problem/2172 在两个序列自动机上同时走,这样暴搜. 先走字典序小的字符,一边搜一边输出,就是按字典序排序的. 方案数很多,需要高精度?空间很小,要压位. ...
- 洛谷P4762 [CERC2014]Virus synthesis(回文自动机+dp)
传送门 回文自动机的好题啊 先建一个回文自动机,然后记$dp[i]$表示转移到$i$节点代表的回文串的最少的需要次数 首先肯定2操作越多越好,经过2操作之后的串必定是一个回文串,所以最后的答案肯定是由 ...
- 序列自动机—— [FJOI2016]所有公共子序列问题
序列自动机: 是一个处理子序列的自动机.就这样. 建造:(By猫老师:immoralCO猫) s[] next[][] memset(next[n], -, <<); for(int i ...
- 洛谷CF264D Colorful Stones(子序列匹配,思维)
洛谷题目传送门 神仙思维题. 对于两个字符串的匹配问题,似乎之前蒟蒻写的HAOI2010最长公共子序列题解中提到的建网格图模型是一种套路? 给一个稍微强一点的样例(把字母换成了ABC) AABCB B ...
- [洛谷P4609] [FJOI2016]建筑师
洛谷题目链接:[FJOI2016]建筑师 题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 \(n\) 个建筑,每个建筑的高度是 \(1\) 到 \(n\) 之间的一 ...
- 洛谷 P4609: [FJOI2016] 建筑师
本省省选题是需要做的. 题目传送门:洛谷P4609. 题意简述: 求有多少个 \(1\) 到 \(N\) 的排列,满足比之前的所有数都大的数正好有 \(A\) 个,比之后的所有数都大的数正好有 \(B ...
随机推荐
- shell 参数
转:http://hi.baidu.com/ipvsadm/item/489d9e16460195ddbe9042ee linux中shell变量$#,$@,$0,$1,$2的含义解释 linux中s ...
- mysql增删改查、连表查询、常用操作
一.建表 1.最简单的建表CREATE TABLE user(id int,name char(20),age int); 2.带主键带注释和默认值创建表CREATE TABLE user(id I ...
- 心中忐忑的跨进了Python的大门!
Hello!大家好,我是Jmmy 作为一个python初学者,抱着一种忐忑的心里走进了这扇让我有些胆怯的大门,因为零基础的缘故让我不得不再三去考虑学这门语言,英语.数学都是个渣的我,也许注定会止步门外 ...
- Python基础入门(模块和包)
1 模块 1.1 什么是模块 在 Python 中,一个 .py 文件就称之为一个模块(Module). 我们学习过函数,知道函数是实现一项或多项功能的一段程序 .其实模块就是函数功能的扩展.为什么这 ...
- Spark配置参数的三种方式
1.Spark 属性Spark应用程序的运行是通过外部参数来控制的,参数的设置正确与否,好与坏会直接影响应用程序的性能,也就影响我们整个集群的性能.参数控制有以下方式:(1)直接设置在SparkCon ...
- Python 日志记录与程序流追踪(基础篇)
日志记录(Logging) More than print: 每次用 terminal debug 时都要手动在各种可能出现 bug 的地方 print 相关信息来确认 bug 的位置: 每次完成 d ...
- DeepLearning - Regularization
I have finished the first course in the DeepLearnin.ai series. The assignment is relatively easy, bu ...
- Ubuntu系统下在PyCharm里用virtualenv集成TensorFlow
我的系统环境 Ubuntu 18.04 Python3.6 PyCharm 2018.3.2 community(免费版) Java 1.8 安装前准备 由于众所周知的原因,安装中需要下载大量包,尽量 ...
- eBay报告:德国或将成为外贸电商热门市场
[亿邦动力网讯]1月3日消息,日前,跨境电商平台eBay发布公告称,自2014年1月中旬起,卖家在eBay德国 ( eBay.de ).eBay 奥地利 ( eBay.at ) 或eBay瑞士 ( e ...
- LeetCode 206. Reverse Linked List(C++)
题目: Reverse a singly linked list. Example: Input: 1->2->3->4->5->NULL Output: 5->4 ...