Codeforces 235 C
题目大意
给定一个模板串, 再给出\(n\)个询问, 询问每一个串的循环串总共在原串中出现了多少次.
循环串: 比如说有\(str[] = \{ABCD\}\), 则其循环串有\(\{ABCD\}, \{BCDA\}, \{CDAB\}, \{DABC\}\), 共\(len\)个.
题解
把每一个串复制一遍放在原串后面: \(\{ABCD\} \to \{ABCDABC\}\), 放入原串的后缀自动机中匹配. 在匹配时, 假如下一位无法匹配, 则跳suffix link; 假如即使跳了suffix link, 最大长度\(len(suffix)\)仍然大于等于原串长度, 则也跳suffix link(相当于砍掉多余的部分).
放入SAM前要先跑一次KMP去循环节.
#include <cstdio>
#include <cstring>
#include <vector>
const int LEN = (int)1e6;
struct suffixAutomaton
{
struct state
{
state *suc[26], *pre;
int len;
int sz, tg;
std::vector<state*> bck;
inline state()
{
for(int i = 0; i < 26; ++ i)
suc[i] = NULL;
pre = NULL;
sz = 1;
bck.clear();
tg = 0;
}
};
state *rt, *lst;
inline void insert(int c)
{
state *u = new state;
u->len = lst->len + 1;
for(; lst != NULL && lst->suc[c] == NULL; lst->suc[c] = u, lst = lst->pre);
if(lst == NULL)
u->pre = rt;
else
{
state *p = lst->suc[c];
if(p->len == lst->len + 1)
u->pre = p;
else
{
state *q = new state;
*q = *p;
q->len = lst->len + 1, q->sz = 0;
p->pre = u->pre = q;
for(; lst != NULL && lst->suc[c] == p; lst->suc[c] = q, lst = lst->pre);
}
}
lst = u;
}
void DFS(state *u)
{
u->tg = 1;
if(u->pre != NULL)
u->pre->bck.push_back(u);
for(int i = 0; i < 26; ++ i)
if(u->suc[i] != NULL && ! u->suc[i]->tg)
DFS(u->suc[i]);
}
void get(state *u)
{
for(std::vector<state*>::iterator p = u->bck.begin(); p != u->bck.end(); ++ p)
get(*p), u->sz += (*p)->sz;
}
inline void build(char *str, int len)
{
lst = rt = new state;
rt->len = 0;
for(int i = 0; i < len; ++ i)
insert(str[i] - 'a');
DFS(rt);
get(rt);
}
inline int match(char *str, int len, int cir)
{
state *u = rt;
int cur = 0;
long long ans = 0;
for(int i = 0; i < len + cir - 1; ++ i)
{
for(; u != rt && u->suc[str[i] - 'a'] == NULL; cur = u->pre->len, u = u->pre);
if(u->suc[str[i] - 'a'] != NULL)
u = u->suc[str[i] - 'a'], ++ cur;
for(; u != rt && u->pre->len >= len; cur = u->pre->len, u = u->pre);
if(cur >= len)
ans += u->sz;
}
return ans;
}
}SAM;
int main()
{
#ifndef ONLINE_JUDGE
freopen("CF235C.in", "r", stdin);
#endif
static char str[LEN];
scanf("%s", str);
int len = strlen(str);
SAM.build(str, len);
int n;
scanf("%d\n", &n);
for(int i = 0; i < n; ++ i)
{
static char str[LEN << 1];
scanf("%s", str);
int len = strlen(str);
static int nxt[LEN];
nxt[0] = -1;
int p = nxt[0];
for(int i = 1; i < len; ++ i)
{
for(; ~ p && str[i] ^ str[p + 1]; p = nxt[p]);
nxt[i] = str[i] == str[p + 1] ? ++ p : p;
}
int cir = len % (len - nxt[len - 1] - 1) == 0 ? len - nxt[len - 1] - 1 : len;
for(int i = 0; i < cir; ++ i)
str[i + len] = str[i];
printf("%d\n", SAM.match(str, len, cir));
}
}
Codeforces 235 C的更多相关文章
- [codeforces 235]A. LCM Challenge
[codeforces 235]A. LCM Challenge 试题描述 Some days ago, I learned the concept of LCM (least common mult ...
- codeforces 235 div2 C Team
题目:http://codeforces.com/contest/401/problem/C 题意:n个0,m个1,求没有00或111的情况. 这么简单的题..... 做题的时候脑残了...,今天,贴 ...
- codeforces 235 B. Let's Play Osu!
You're playing a game called Osu! Here's a simplified version of it. There are n clicks in a game. F ...
- codeforces 235 div2 B. Sereja and Contests
Sereja is a coder and he likes to take part in Codesorfes rounds. However, Uzhland doesn't have good ...
- codeforces 235 div2 A. Vanya and Cards
Vanya loves playing. He even has a special set of cards to play with. Each card has a single integer ...
- Codeforces 235 E Number Challenge
Discription Let's denote d(n) as the number of divisors of a positive integer n. You are given three ...
- codeforces 235 B lets play osu!
cf235B 一道有意思的题.(据说是美少女(伪)计算机科学家出的,hh) 根据题目要求,就是求ni^2的和. 而n^2=n*(n-1)+n; n*(n-1)=C(n,2)*2: 所以∑ai^2=∑a ...
- [ BZOJ 4318 & 3450 / CodeForces 235 B ] OSU!
\(\\\) \(Description\) 一共进行\(N\)次操作,生成一个长度为\(N\)的\(01\)序列,成功对应\(1\),失败对应\(0\),已知每一次操作的成功率\(p_i\). 在这 ...
- Codeforces Round #235 (Div. 2) D. Roman and Numbers 状压dp+数位dp
题目链接: http://codeforces.com/problemset/problem/401/D D. Roman and Numbers time limit per test4 secon ...
随机推荐
- L2-006 树的遍历 RTA
L2-006 树的遍历(25 分) 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(<=30),是二叉树 ...
- electron 安装
1.从网上下载的是nodejs的v0.10.42版本的安装文件,安装node-v0.10.42-x86.msi都使用默认安装,安装完成后会安装在C:\Program Files\nodejs\目录下, ...
- PHP define() 定义常量
PHP define()函数定义了运行时的常量, 具体语法如下所示: (PHP 4, PHP 5, PHP 7) define — Defines a named constant bool defi ...
- how can I ues Dataset to shuffle a large whole dataset?
The Dataset.shuffle() implementation is designed for data that could be shuffled in memory; we're co ...
- C#-SqlServer连接
C#连接数据库在类方面没有java通用,不同数据库有不同的类库.在这里只做了SqlServer的连接类. public class DbLink { private string config = C ...
- Jeddict:从服务器的验证过程,思考学习新事物的套路
结合一路研究Jeddict使用的过程经验来看,在这里说一下关于服务器配置的东西.在我们团队,最开始用这个插件的时候,因为公司用的应用服务器是Jboss EAP 7,所以,我们自然而然的,想当然的直接使 ...
- BZOJ2326 [HNOI2011]数学作业 【矩阵快速幂】
题解 我们设f[i]表示前i个数模M意义下的答案 则f[i] = f[i - 1] * 100...0 + i[i是几位就有几个0] 可以写出矩阵递推式: 之后按位数分组矩乘就好了 #include& ...
- 刷题总结——探险(ssoj)
题目: 国家探险队长 Jack 意外弄到了一份秦始皇的藏宝图,于是,探险队一行人便踏上寻宝之旅,去寻找传说中的宝藏. 藏宝点分布在森林的各处,每个点有一个值,表示藏宝的价值.它们之间由一些小路相连,小 ...
- 刷题总结——array(ssoj)
题目: 题目描述 给定 2 个正整数序列 A1, A2,序列长度分别为 L1, L2.你可以进行以下的一次操作:1. 选择两个数 K1,K2(1≤K1≤L1, 1≤K2≤L2):2. 移去 A1 中最 ...
- [转] Makefile 基础 (8) —— Makefile 隐含规则
该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客:(最原始版本) http://blog.csdn.net/haoel/article/details/2886 我转自 ...