问题描述:先给你s个禁止串,求不包含禁止串的最长串,如果存在,打印字典序最大。

数据范围:s <= 1000, 禁止串长度不超过50。

分析:不匹配问题实际上等同于匹配问题。假设我们已经有满足条件的串T, 如果加上某个字符c后得到的新串T + c 仍然满足条件,显然

我们便找到了一个更长的串,否则|T|就是所求。我们枚举字符c时,新串是否满足条件取决于原串T的后缀关于所有禁止串在其构成的trie

上的匹配情况,这也就是我们需要并且仅需要维护的信息。具体的说,我们记录串T在trie中匹配最深的节点编号,假设为l(T),当在T尾部

追加字符c时:

l(T) = nex[l(T)][c]

T = T + c

如果更新后得到的l(T)不在任一个禁止节点上,新串便是符合要求的。

如此我们看,若存在一个长度有限的最长串T,那么在T后追加任一个字符c后都会使得l(T + c)落在某个禁止节点上。考虑nex数组的计算:

nex[i][j]表示节点i对应的前缀追加字符j后在trie中匹配最深的节点编号。显然:

nex[i][j] = ch[i][j] ? ch[i][j] : ch[fail[i]][j]]

这里fail[i]表示节点i对应的前缀的后缀(不包括其本身)在trie中匹配最深的节点编号,即AC自动机中的失配函数。

将nex数组合并到ch数组中:

ch[i][j] = nex[i][j]

于是由trie中所有节点关于ch函数构成的一张有向图,并且将某些节点标记为禁止节点当且仅的其对应的前缀为某个禁止串。

因此考虑删去禁止节点后的新图G = (V, A), 合法串与图上的路径有一一对应关系,最长串存在当且仅当 |V| > 1(不能仅包含trie中0节点)

且图中无环。

判断一张有向图是否是DAG可以使用栈的性质,栈中存储dfs搜索经过的链节点,若新点不在链中即可加入,否则证明有环。

 #include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <iostream>
#include <assert.h>
#define pi acos(-1.)
using namespace std;
typedef long long ll;
const int int_inf = 0x3f3f3f3f;
const ll ll_inf = 1ll << ;
const int INT_INF = (int)((1ll << ) - );
const int mod = 1e9 + ;
const double double_inf = 1e30;
typedef unsigned long long ul;
#pragma comment(linker, "/STACK:102400000,102400000")
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define mp make_pair
#define st first
#define nd second
#define keyn (root->ch[1]->ch[0])
#define lson (u << 1)
#define rson (u << 1 | 1)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define type(x) __typeof(x.begin())
#define foreach(i, j) for(type(j)i = j.begin(); i != j.end(); i++)
#define FOR(i, s, t) for(int i = (s); i <= (t); i++)
#define ROF(i, t, s) for(int i = (t); i >= (s); i--)
#define dbg(x) cout << x << endl
#define dbg2(x, y) cout << x << " " << y << endl
#define clr(x, i) memset(x, (i), sizeof(x))
#define maximize(x, y) x = max((x), (y))
#define minimize(x, y) x = min((x), (y))
#define low_bit(x) ((x) & (-x)) inline int readint(){
int x;
scanf("%d", &x);
return x;
} inline int readstr(char *s){
scanf("%s", s);
return strlen(s);
} class cmpt{
public:
bool operator () (const int &x, const int &y) const{
return x > y;
}
}; int Rand(int x, int o){
//if o set, return [1, x], else return [0, x - 1]
if(!x) return ;
int tem = (int)((double)rand() / RAND_MAX * x) % x;
return o ? tem + : tem;
} void data_gen(){
srand(time());
freopen("in.txt", "w", stdout);
int times = ;
printf("%d\n", times);
while(times--){
int n = Rand(, ), m = Rand(, );
printf("%d %d\n", n, m);
FOR(i, , n){
FOR(j, , m) printf("%c", Rand(, ) + 'a');
putchar('\n');
}
n = Rand(min(, n), ), m = Rand(min(, m), );
printf("%d %d\n", n, m);
FOR(i, , n){
FOR(j, , m) printf("%c", Rand(, ) + 'a');
putchar('\n');
}
}
} struct cmpx{
bool operator () (int x, int y) { return x > y; }
};
int debug = ;
int dx[] = {-, , , };
int dy[] = {, , -, };
//-------------------------------------------------------------------------
const int maxn = 1e3 + ;
const int maxm = ;
int sigma_size, tot;
struct Trie{
int ch[maxn * maxm][];
int sz;
int info[maxn * maxm];
int fail[maxn * maxm];
int ans[maxn * maxm];
int ok[maxn * maxm];
void init() { sz = tot = ; clr(ch[], ); clr(info, ); }
int idx(char c) { return c - 'A'; }
void insert(char *s){
int u = ;
while(*s){
int v = ch[u][idx(*s)];
if(!v) { ch[u][idx(*s)] = v = ++sz; clr(ch[sz], ); }
u = v;
++s;
}
if(!info[u]) info[u] = ++tot;
}
void getFail(){
queue<int> q;
while(!q.empty()) q.pop();
FOR(i, , sigma_size - ) if(ch[][i]) q.push(ch[][i]);
FOR(i, , sigma_size - ) fail[ch[][i]] = ;
while(!q.empty()){
int u = q.front(); q.pop();
FOR(i, , sigma_size - ){
int v = ch[u][i];
if(!v) { ch[u][i] = ch[fail[u]][i]; continue; }
fail[v] = ch[fail[u]][i];
q.push(v);
}
}
} bool vis[maxn * maxm];
bool dfs(int u){
if(vis[u]) return true;
if(ok[u] != -) return ok[u];
if(info[u]) return ok[u] = ;
vis[u] = ;
FOR(i, , sigma_size - ){
int v = ch[u][i];
if(dfs(v)) { vis[u] = ; return ok[u] = ; }
}
vis[u] = ;
return ok[u] = ;
} bool isAcy(){
clr(ok, -), clr(vis, );
return !dfs();
} int __dfs(int u){
if(ans[u] != -) return ans[u];
if(info[u]) return ans[u] = ;
int maxi = ;
FOR(i, , sigma_size - ){
int v = ch[u][i];
int tem = __dfs(v);
maximize(maxi, tem);
}
return ans[u] = maxi + ;
}
int getAns(){
clr(ans, -);
return __dfs();
}
void printAns(int u, int d){
if(info[u]) return;
ROF(i, sigma_size - , ){
int v = ch[u][i];
if(ans[v] == d - ){
if(ans[v] > ) putchar(i + 'A');
printAns(v, d - );
return;
}
}
}
}trie;
int n;
char s[maxm];
//-------------------------------------------------------------------------
int main(){
//data_gen(); return 0;
//C(); return 0;
debug = ;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(debug) freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int T = readint();
while(T--){
sigma_size = readint(), n = readint();
trie.init();
FOR(i, , n){
readstr(s);
trie.insert(s);
}
trie.getFail();
int ans;
if(!trie.isAcy()) ans = ;
else ans = trie.getAns();
if(ans > ) trie.printAns(, ans), putchar('\n');
else puts("No");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
return ;
}

code:

LA 3907 Puzzle的更多相关文章

  1. BZOJ 3907: 网格

    Description 求不跨过直线 \(y=x\) ,到达 \((n,m)\) 的方案数. Sol 组合数学+高精度. 这个推导过程跟 \(Catalan\) 数是一样的. 答案就是 \(C^{n+ ...

  2. POJ 1651 Mulitiplication Puzzle

    The multiplication puzzle is played with a row of cards, each containing a single positive integer. ...

  3. Puzzle 面向服务/切面(AOP/IOC)开发框架 For .Net

    Puzzle 面向服务/切面AOP开发框架 For .Net AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效 ...

  4. leggere la nostra recensione del primo e del secondo

    La terra di mezzo in trail running sembra essere distorto leggermente massima di recente, e gli aggi ...

  5. Le lié à la légèreté semblait être et donc plus simple

    Il est toutefois vraiment à partir www.runmasterfr.com/free-40-flyknit-2015-hommes-c-1_58_59.html de ...

  6. HDU5456 Matches Puzzle Game(DP)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5456 Description As an exciting puzzle game for ...

  7. one recursive approach for 3, hdu 1016 (with an improved version) , permutations, N-Queens puzzle 分类: hdoj 2015-07-19 16:49 86人阅读 评论(0) 收藏

    one recursive approach to solve hdu 1016, list all permutations, solve N-Queens puzzle. reference: t ...

  8. poj3678 Katu Puzzle 2-SAT

    Katu Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6714   Accepted: 2472 Descr ...

  9. POJ1651Multiplication Puzzle[区间DP]

    Multiplication Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8737   Accepted:  ...

随机推荐

  1. SSH 25 tips

    port ssh -Nf -L 9800:192.168.1.132:22 -l root 10.100.125.76 -v ssh -l root 127.0.0.1 -p 9800 scp -P ...

  2. Java基础之处理事件——应用程序中的语义事件监听器(Sketcher 5 with element color listeners)

    控制台程序. 为了标识元素的类型,可以为菜单已提供的4中元素定义常量,用作ID.这有助于执行菜单项监听器的操作,还提供了一种标识颜色类型的方式.我们会累积许多应用程序范围的常量,所以把它们定义为可以静 ...

  3. mongodb的基本操作与插入文档(document)

    一.mongodb的基本操作: 1.查看mongodb当前所有的databases : show dbs 2.选择数据库(database) : use databaseName(该数据库不存在则会自 ...

  4. (Protype Pattern)原型模式

    定义: 原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象 适用性: 当我们系统中有一些类,在使用的时候都有同样需要大量的创建,而这样的创建是复杂的而且是浪费CPU,内存资源的 ...

  5. Lintcode: Previous Permuation

    Given a list of integers, which denote a permutation. Find the previous permutation in ascending ord ...

  6. 3D照片放大展示窗口

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  7. paper 27 :图像/视觉显著性检测技术发展情况梳理(Saliency Detection、Visual Attention)

    1. 早期C. Koch与S. Ullman的研究工作. 他们提出了非常有影响力的生物启发模型. C. Koch and S. Ullman . Shifts in selective visual ...

  8. PAT乙级 1002. 写出这个数 (20)

    1002. 写出这个数 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 读入一个自然数n,计算其各位数字 ...

  9. Visual studio 中编译错误SQL71006: Only one statement is allowed per batch. A batch separator, such as 'GO', might be required between statements.

    把写好的sql脚本,并在mssqlmanager里面编译成功的存储过程脚本复制到vs项目下,出现错误信息如下:SQL71006: Only one statement is allowed per b ...

  10. startActivityForResult 页面跳转回调

    import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util. ...