题目链接

洛谷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. 【MYSQL命令】mysql基础命令

    1.查询MYSQL当前用户命令:select user() mysql> select user(); +------------------------+ | user() | +------ ...

  2. css布局笔记(一)

    布局方式 一列布局 通常固定宽高,用margin:0 auto:居中显示 两列布局 说起两列布局,最常见的就是使用float来实现.float浮动布局的缺点是浮动后会造成文本环绕等效果,以及需要及时清 ...

  3. MongoDB Chapter1:Introduction

    你是在防火墙后面吗? 为了继续本课程,您必须能够将计算机的传出请求发送到我们在MongoDB Atlas中设置的数据库服务器.这些服务器在Amazon AWS中的端口27017上运行. 请单击http ...

  4. Pearson Distance

    Pearson Distance: where: 1.  is the covariance 2.  is the standard deviation of 3.  is the standard ...

  5. Qt应用程序重启

    重启应用程序是一种常见的操作,在Qt中实现非常简单,需要用到QProcess类一个静态方法: // program, 要启动的程序名称 // arguments, 启动参数 bool startDet ...

  6. 初创型公司如何经济有效的申请邓白氏编码(DUNS)

    听说有免费,和800元,1500元,上万元等不同的申请方式?听说申请完还要等十数个工作日让邓白氏和苹果的数据库同步.不同高低价格的申请方式得到的编码都能被苹果接受吗? http://www.zhihu ...

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

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

  8. Spark Shuffle之Hash Shuffle

    源文件放在github,如有谬误之处,欢迎指正.原文链接https://github.com/jacksu/utils4s/blob/master/spark-knowledge/md/hash-sh ...

  9. 在Wmware虚拟机上如何检查是否CPU支持虚拟化 和 加载kvm模块

    在vm虚拟机中 修改 虚拟机==>设置==> 处理器==>虚拟化引擎(选第二项:虚拟化Intel VT-x/EPT 或 AMD-V/RVI(V) )     # vmx或svm :表 ...

  10. 【Mark】Android应用开发SharedPreferences存储数据的使用方法

    Android应用开发SharedPreferences存储数据的使用方法 SharedPreferences是Android中最容易理解的数据存储技术,实际上SharedPreferences处理的 ...