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 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
随机推荐
- 利用类装饰器自定制property实现延迟计算
class LazyProperty: ''' hello,我是非数据描述符(没有定义__set__,不然是大哥数据描述符了--!) ''' def __init__(self, func): pri ...
- Python之套接字
Python之套接字 客户端Client/服务端Server架构: 1.硬件C/S架构 2.软件C/S架构 OSI4层:4层里有五层,五层里又有7层. 四层---------五层--------七层 ...
- Fiddler基本用法:手机抓包1
Fiddler基本用法以及如何对手机抓包 一.Fiddler是什么? ·一种Web调试工具. ·可以记录所有客户端和服务器的http和https请求. ·允许监视.设置断点.修改输入输出数据. 官方文 ...
- 总结:常用的Linux系统监控命令(2)
判断I/O瓶颈 mpstat命令 命令:mpstat -P ALL 1 1000 结果显示: 注意一下这里面的%iowait列,CPU等待I/O操作所花费的时间.这个值持续很高通常可能是I/O瓶颈所导 ...
- [luoguP2957] [USACO09OCT]谷仓里的回声Barn Echoes(Hash)
传送门 团队里的hash水题,数据小的不用hash都能过.. 也就是前缀hash,后缀hash,再比较一下就行. ——代码 #include <cstdio> #include <c ...
- 【bzoj3747】[POI2015]Kinoman - 线段树(经典)
Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l< ...
- 守卫者的挑战(codevs 1997)
题目描述 Description 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜寻着关押applepi的监狱的所在地.突然,眼前一道亮光闪过.“我,Nizem,是黑魔法圣殿的守卫者.如 ...
- android 实现照相功能 照片存放在SID卡中,将照片显示在Image中
protected static final int CAMERA_RESULT = 0; private String fileName; private Button takePhotoBn; p ...
- POJ 3468_A Simple Problem with Integers(树状数组)
完全不知道该怎么用,看书稍微懂了点. 题意: 给定序列及操作,求区间和. 分析: 树状数组可以高效的求出连续一段元素之和或更新单个元素的值.但是无法高效的给某一个区间的所有元素同时加个值. 不能直接用 ...
- 使用HttpClient调用第三方接口
最近项目中需要调用第三方的Http接口,这里我用到了HttpClient. 首先我们要搞明白第三方接口中需要我们传递哪些参数.数据,搞明白参数以后我们就可以使用HttpClient调用接口了. 1.调 ...