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 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
随机推荐
- Django之Ajax提交
Ajax 提交数据,页面不刷新 Ajax要引入jQuery Django之Ajax提交 Js实现页面的跳转: location.href = "/url/" $ajax({ url ...
- DFS求连通块(漫水填充法)
G - DFS(floodfill),推荐 Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I6 ...
- Linux学习总结(22)——CentOS7.2安装Nginx
一.使用Yum安装(推荐) 使用Yum安装是推荐的方式,整体的流程非常的简单,也不容易出错,如果不需要什么特殊配置,建议使用Yum尽进行安装. 1.安装epel-release源并进行安装 1 2 3 ...
- stm32 调试时卡在LDR R0, =SystemInit
网上找到的可能的原因 堆栈空间默认的太小 默认startup_stm32f10x_hd.s中 Stack_Size EQU 0x00000400,如果改大之后,可能调试就可以正常运行. 出现最多的情况 ...
- [codeforces471D]MUH and Cube Walls
[codeforces471D]MUH and Cube Walls 试题描述 Polar bears Menshykov and Uslada from the zoo of St. Petersb ...
- Spring Data JPA 之 一对一,一对多,多对多 关系映射
一.@OneToOne关系映射 JPA使用@OneToOne来标注一对一的关系. 实体 People :用户. 实体 Address:家庭住址. People 和 Address 是一对一的关系. 这 ...
- 【ZJOI2017 Round1练习】D8T2 sequence(DP)
题意: 思路: #include <algorithm> #include <iostream> #include <cstring> #include <c ...
- NOIP2012 文化之旅
题目描述 Description 有一位使者要游历各国,他每到一个国家,都能学到一种文化,但他不愿意学习任何一种文化超过一次(即如果他学习了某种文化,则他就不能到达其他有这种文化的国家).不同的国家可 ...
- linux 常见名词及命令(五)
计划任务服务之一次性任务: at <时间> 安排一次性任务 atq 或at -l 查看任务列表 at -c 序号 预览任务与设置环境 atrm 序号 删除任务 安排任务示例: 在23:30 ...
- view属性大全