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 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
随机推荐
- buf.compare()
buf.compare(otherBuffer) otherBuffer {Buffer} 返回:{Number} 比较两个 Buffer 实例,无论 buf 在排序上靠前.靠后甚至与 otherBu ...
- stark组件之删除页面内容搭建(八)
删除页面没有太多的内容和功能 def del_view(self, request,pk,*args,**kwargs): """ 处理删除表弟 :param reque ...
- JS 去除字符串空格
$.trim()是jQuery提供的函数,用于去掉字符串首尾的空白字符. "abc 123 def".replace(/\s/g, "") 去除所有的空格
- UVa 712 S-Trees(二进制转换 二叉树叶子)
题意: 给定一颗n层的二叉树的叶子, 然后给定每层走的方向, 0代表左边, 1代表右边, 求到达的是那一个叶子. 每层有一个编号, 然后n层的编号是打乱的, 但是给的顺序是从1到n. 分析: 先用一个 ...
- 将scl分频
多个scl后一个高脉冲,脉冲宽度一个scl脉冲. always @ ( posedge MCLK or negedge RST_N ) begin if (rClkCount == 24) //如果有 ...
- Thawte SSL Web Server 多域型SSL证书
Thawte SSL Web Server 多域型SSL证书,最多支持25个域名,需要验证域名所有权和申请单位信息,属于企业验证型SSL证书,提供40位/56位/128位,最高支持256位自适应加密. ...
- BNUOJ 6023 畅通工程续
畅通工程续 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 1874 ...
- 九度oj 题目1057:众数
题目1057:众数 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:9744 解决:3263 题目描述: 输入20个数,每个数都在1-10之间,求1-10中的众数(众数就是出现次数最多的数, ...
- Linux下汇编语言学习笔记26 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...
- ZOJ 1298_Domino Effect
题意: 多米诺骨牌效应:若干个关键牌相连,关键牌之间含有普通牌,关键牌倒下后其所在的行的普通牌全部倒下.求从推倒1号关键牌开始,最终倒下的牌的位置及时间. 分析: 最终倒下的牌的位置有两种情况,要么是 ...