SAM入门
学了两天,会了点皮毛,这里只放代码。
P3804
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N = 1e6 + ;
struct node
{
int ch[];
int len,fa;
node()
{
clean(ch);
len = ;
}
}dian[N << ];
int las = ,tot = ;
int len;
char s[N];
int buc[N << ],siz[N << ],pos[N << ];
inline void add(int c)
{
int p = las;int np = las = ++tot;
dian[np].len = dian[p].len + ;
for(;p && !dian[p].ch[c];p = dian[p].fa)
dian[p].ch[c] = np;
if(!p) dian[np].fa = ;
else
{
int q = dian[p].ch[c];
if(dian[q].len == dian[p].len + ) dian[np].fa = q;
else
{
int nq = ++tot;
dian[nq] = dian[q];
dian[nq].len = dian[p].len + ;
dian[q].fa = dian[np].fa = nq;
for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq;
}
}
siz[np] = ;
}
/*void add(int c)
{
int p=las;int np=las=++tot;
dian[np].len=dian[p].len+1;
for(;p&&!dian[p].ch[c];p=dian[p].fa)dian[p].ch[c]=np;
if(!p)dian[np].fa=1;//以上为case 1
else
{
int q=dian[p].ch[c];
if(dian[q].len==dian[p].len+1)dian[np].fa=q;//以上为case 2
else
{
int nq=++tot;dian[nq]=dian[q];
dian[nq].len=dian[p].len+1;
dian[q].fa=dian[np].fa=nq;
for(;p&&dian[p].ch[c]==q;p=dian[p].fa)dian[p].ch[c]=nq;//以上为case 3
}
}
siz[las = np] = 1;
}*/
inline int dfs()
{
int ret = ;
duke(i,,tot)
++buc[dian[i].len];
duke(i,,tot)
buc[i] += buc[i - ];
duke(i,,tot)
pos[buc[dian[i].len]--] = i;
for(int i = tot;i;i--)
{
int now = pos[i];
siz[dian[now].fa] += siz[now];
if(siz[now] > )
ret = max(ret,siz[now] * dian[now].len);
}
return ret;
}
int main()
{
scanf("%s",s);
len = strlen(s);
duke(i,,len - )
{
add(s[i] - 'a');
}
printf("%d\n",dfs());
return ;
}
SP1811
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N = ;
struct node
{
int fa,len;
int ch[];
node()
{
len = ;
clean(ch);
}
}dian[N << ];
int tot = ,las = ,len1,len2;
char s1[N],s2[N];
inline void add(int c)
{
int p = las;int np = las = ++tot;
dian[np].len = dian[p].len + ;
for(;p && !dian[p].ch[c];p = dian[p].fa)
dian[p].ch[c] = np;
if(!p) dian[np].fa = ;
else
{
int q = dian[p].ch[c];
if(dian[q].len == dian[p].len + ) dian[np].fa = q;
else
{
int nq = ++tot;
dian[nq] = dian[q];
dian[nq].len = dian[p].len + ;
dian[q].fa = dian[np].fa = nq;
for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq;
}
}
}
inline int Max(int x,int y)
{
return x < y ? y : x;
}
inline int lcs(char *s)
{
int n = strlen(s),ret = ;
for(int i = ,p = ,l = ;i < n;++i)
{
int c = s[i] - 'a';
if(dian[p].ch[c] != ) l++,p = dian[p].ch[c];
else
{
for(;p && !dian[p].ch[c];p = dian[p].fa) ;
if(!p) l = ,p = ;
else
{
l = dian[p].len + ;
p = dian[p].ch[c];
}
}
ret = Max(ret,l);
}
return ret;
}
int main()
{
scanf("%s",s1);
scanf("%s",s2);
len1 = strlen(s1);
len2 = strlen(s2);
for(register int i = ;i < len1;++i)
{
add(s1[i] - 'a');
}
printf("%d\n",lcs(s2));
return ;
}
SP1812
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N = 1e5 + ;
struct node
{
int fa,len;
int ch[];
node()
{
clean(ch);
len = ;
}
} dian[N << ];
char s1[N],s2[N];
int las = ,tot = ;
inline void add(int c)
{
int p = las;
int np = las = ++tot;
dian[np].len = dian[p].len + ;
for(; p && !dian[p].ch[c]; p = dian[p].fa)
dian[p].ch[c] = np;
if(!p) dian[np].fa = ;
else
{
int q = dian[p].ch[c];
if(dian[q].len == dian[p].len + ) dian[np].fa = q;
else
{
int nq = ++tot;
dian[nq] = dian[q];
dian[nq].len = dian[p].len + ;
dian[q].fa = dian[np].fa = nq;
for(; p && dian[p].ch[c] == q; p = dian[p].fa) dian[p].ch[c] = nq;
}
}
}
int pos[N << ],buc[N << ],Max[N << ],Min[N << ];
inline void dfs(char *s)
{
int n = strlen(s);
for(int i = ,p = ,l = ; i < n; ++i)
{
int c = s[i] - 'a';
for(; p && !dian[p].ch[c];) p = dian[p].fa,l = dian[p].len;
if(!p) l = ,p = ;
else
{
l ++;
p = dian[p].ch[c];
Max[p] = max(Max[p],l);
}
}
for(int i = tot; i >= ; --i)
{
int now = pos[i],f = dian[now].fa;
Max[f] = max(Max[f],min(Max[now],dian[f].len));
Min[now] = min(Min[now],Max[now]);
Max[now] = ;
}
}
void sort()
{
duke(i,,tot)
++buc[dian[i].len];
duke(i,,tot)
buc[i] += buc[i - ];
duke(i,,tot)
pos[buc[dian[i].len] --] = i;
}
int main()
{
scanf("%s",s1);
int len1 = strlen(s1);
for(register int i = ; i < len1; ++i)
{
add(s1[i] - 'a');
}
sort();
memset(Min,0x3f,sizeof(Min));
clean(Max);
while(scanf("%s",s2) != EOF)
{
dfs(s2);
}
int ans = ;
duke(i,,tot)
ans = max(ans,Min[i]);
printf("%d\n",ans);
return ;
}
P2852 [USACO06DEC]牛奶模式Milk Patterns
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N = 2e4 + ;
struct node
{
int len,fa;
int ch[];
node()
{
clean(ch);
len = ;
}
}dian[N << ];
int las = ,tot = ;
int n,k;
int x,pos[N << ],siz[N << ];
void add(int c)
{
int p = las;int np = las = ++tot;
dian[np].len = dian[p].len + ;
siz[np] = ;
for(;p && !dian[p].ch[c];p = dian[p].fa)
dian[p].ch[c] = np;
if(!p) dian[np].fa = ;
else
{
int q = dian[p].ch[c];
if(dian[q].len == dian[p].len + )
dian[np].fa = q;
else
{
int nq = ++tot;
dian[nq] = dian[q];
dian[nq].len = dian[p].len + ;
dian[q].fa = dian[np].fa = nq;
for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq;
}
}
}
int dfs()
{
int ret = ;
for(int i = ;i <= tot;i++)
pos[i] = i;
sort(pos + ,pos + tot + ,[=](int &a,int &b){return dian[a].len > dian[b].len;});
for(int i = ;i <= tot;++i)
{
siz[dian[pos[i]].fa] += siz[pos[i]];
if(siz[pos[i]] >= k)
{
ret = max(ret,dian[pos[i]].len);
}
}
return ret;
}
int main()
{
read(n);read(k);
for(int i = ;i <= n;++i)
read(x),add(x);
printf("%d\n",dfs());
return ;
}
P3975 [TJOI2015]弦论
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N = 5e5 + ;
struct node
{
int len,fa;
int ch[];
}dian[N << ];
char s[N];
int las = ,tot = ;
int n,k,flg;
int x,pos[N << ],siz[N << ],buc[N << ],sum[N << ];
void add(int c)
{
int p = las;int np = las = ++tot;
dian[np].len = dian[p].len + ;
siz[np] = ;
for(;p && !dian[p].ch[c];p = dian[p].fa)
dian[p].ch[c] = np;
if(!p) dian[np].fa = ;
else
{
int q = dian[p].ch[c];
if(dian[q].len == dian[p].len + )
dian[np].fa = q;
else
{
int nq = ++tot;
dian[nq] = dian[q];
dian[nq].len = dian[p].len + ;
dian[q].fa = dian[np].fa = nq;
for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq;
}
}
}
inline void dfs()
{
for(int i = ; i <= tot; ++i)
++buc[dian[i].len];
for(int i = ; i <= tot; ++i)
buc[i] += buc[i - ];
for(int i = ; i <= tot; ++i)
pos[buc[dian[i].len]--] = i;
for(int i = tot; i; --i)
siz[dian[pos[i]].fa] += siz[pos[i]];
for(int i = ; i <= tot; ++i)
{
if(!flg)
sum[i] = siz[i] = ;
else
sum[i] = siz[i];
}
siz[] = ;
for(int i = tot; i; --i)
for(int j = ; j < ; ++j)
if(dian[pos[i]].ch[j])
sum[pos[i]] += sum[dian[pos[i]].ch[j]];
}
inline void print(int k)
{
if(sum[] < k)
{
printf("-1\n");
return;
}
int now = ;
k -= siz[now];
while(k)
{
int c = ;
while(k > sum[dian[now].ch[c]])
{
k -= sum[dian[now].ch[c++]];
}
now = dian[now].ch[c];
putchar('a' + c);
k -= siz[now];
}
}
int main()
{
scanf("%s",s);
n = strlen(s);
duke(i,,n << )
dian[i].len = ,clean(dian[i].ch);
duke(i,,n - )
add(s[i] - 'a');
read(flg);read(k);
dfs();
print(k);
puts("");
return ;
}
P4070 [SDOI2016]生成魔咒
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N = 2e5 + ;
struct node
{
int fa;
ll len;
map <int,int> ch;
}dian[N << ];
char s[N];
int las = ,tot = ;
int n,k;
ll ans = ;
int x;
void add(int c)
{
int p = las;int np = las = ++tot;
dian[np].len = dian[p].len + ;
for(;p && !dian[p].ch[c];p = dian[p].fa)
dian[p].ch[c] = np;
if(!p) dian[np].fa = ,ans += dian[np].len;
else
{
int q = dian[p].ch[c];
if(dian[q].len == dian[p].len + )
dian[np].fa = q,ans += dian[np].len - dian[q].len;
else
{
int nq = ++tot;
dian[nq] = dian[q];
dian[nq].len = dian[p].len + ;
ans -= dian[q].len - dian[dian[q].fa].len;
dian[q].fa = dian[np].fa = nq;
ans += dian[nq].len - dian[dian[nq].fa].len;
ans += dian[q].len - dian[nq].len;
ans += dian[np].len - dian[nq].len;
for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq;
}
}
}
int main()
{
read(n);
while(n--)
{
int c;
read(c);
add(c);
printf("%lld\n",ans);
}
return ;
}
SAM入门的更多相关文章
- SAM
后缀自动机能识别字符串S的所有子串,是一个DAG. http://blog.csdn.net/huanghongxun/article/details/51112764 https://blog.xe ...
- SAM(后缀自动机)总结
“写sam是肯定会去写的,这样才学的了字符串,后缀数组又不会用 >ω<, sam套上数据结构的感觉就像回家一样! 里面又能剖分又能线段树合并,调试又好调,我爱死这种写法了 !qwq” SA ...
- maomao的每日动向
\(2019.02.04\) \(Nothing\) \(to\) \(do\). \(2019.02.05\) - 早上睡到\(12\)点 - 中午下午:吃饭串门拜年 - 晚上:吹爆<流浪地球 ...
- POJ 1509 Glass Beads---最小表示法
题意: T组数据,每组数据给出一个字符串,求这个字符串的最小表示发(只要求输出起始位置坐标) SAM入门题(检测板子是否正确). 将字符串S加倍丢进SAM中,然后走字符串长度次,每次贪心的沿最小的边走 ...
- react入门(2)
接着上一次的讲,如果没有看过上一篇文章的小伙伴可以先看一下http://www.cnblogs.com/sakurayeah/p/5807821.html React事件 可以先看一下官网讲解的内容h ...
- spring boot入门例子
最近学习spring boot,总结一下入门的的基础知识 1新建maven项目,修改pom.xml <project xmlns="http://maven.apache.org/PO ...
- 【特别推荐】Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
- MongoDB(2):入门
MongoDB入门教程(包含安装.常用命令.相关概念.使用技巧.常见操作等) http://www.jb51.net/article/51514.htm 这篇文章主要介绍了MongoDB入门教程,包含 ...
- Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
随机推荐
- JavaScript小技巧整理篇(非常全)
能够为大家提供这些简短而实用的JavaScript技巧来提高大家编程能力,这对于我来说是件很开心的事.每天仅花上不到2分钟的时间中,你将可 以读遍JavaScript这门可怕的语言所呈现给我们的特性: ...
- JAVA加载Properties配置资源文件
JAVA加载Properties配置资源文件 制作人:全心全意 配置文件(资源文件):以properties作为拓展名的文件 Java代码是如何加载properties文件的? 必须使用Propert ...
- nohup 忽略所有挂断信号
1.nohup 用途:不挂断地运行命令. 语法:nohup Command [ Arg … ] [ & ] 无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup ...
- Volume 1. Maths - Misc
113 - Power of Cryptography import java.math.BigInteger; import java.util.Scanner; public class Main ...
- 利用类装饰器自定制property实现延迟计算
class LazyProperty: ''' hello,我是非数据描述符(没有定义__set__,不然是大哥数据描述符了--!) ''' def __init__(self, func): pri ...
- Quartz--01
Quartz 调度器(scheduler):定时定频率的去执行任务 任务(job):业务逻辑 触发器(trigger):让任务生效的时间 JobDetail(包含任务实现类,任务信息) trigger ...
- es6(var,let,const,set,map,Array.from())
1.变量声明--var,const,let 1.1 var - (全局作用域,局部作用域)会有变量提升 //第一个小例子 <script> var num = 123; function ...
- Android OkHttp与物理存储介质缓存:DiskLruCache(2)
Android OkHttp与物理存储介质缓存:DiskLruCache(2) 本文在附录文章8,9的基础之上,把Android OkHttp与DiskLruCache相结合,综合此两项技术,实 ...
- 全文搜索(A-3)-推荐系统构建步骤
用户研究 用户建模 系统建造
- TeamViewer & remote control
TeamViewer remote control https://www.teamviewer.com/en/download/windows/ https://dl.tvcdn.de/downlo ...