传送门

写的时候挺蛋疼的。

刚开始的时候思路没跑偏,无非就是建个SAM然后把串开两倍然后在SAM上跑完后统计贡献。但是卡在第二个样例上就是没考虑相同的情况。

然后开始乱搞,发现会出现相同串的只有可能是由一个串无限拼接构成的串,于是上了个KMP来搞循环串..然后就没有然后了

基本上一直处于改了这个错误后又被另一个错误卡着的状态,后来没办法了,翻题解..

然后发现只需要在SAM的节点上开个标记就行了...

越学越傻啊...

至于为什么KMP会挂掉..求dalao评论指出

//Codeforces 235C
//by Cydiater
//2017.1.22
#include <iostream>
#include <queue>
#include <map>
#include <iomanip>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
#define ll long long
#define up(i,j,n)	for(int i=j;i<=n;i++)
#define down(i,j,n)	for(int i=j;i>=n;i--)
#define cmax(a,b)	a=max(a,b)
#define cmin(a,b)	a=min(a,b)
const int MAXN=2e6+5;
const int oo=0x3f3f3f3f;
int rnk[MAXN],N,Right[MAXN],M,len,ans,flag[MAXN];
char s[MAXN];
struct SAM{
	int now,cnt,son[MAXN][26],step[MAXN],pre[MAXN],label[MAXN];
	SAM(){now=cnt=1;}
	void Extend(int nxt){
		int p=now,np=++cnt;now=np;
		step[np]=step[p]+1;Right[np]=1;
		for(;(!son[p][nxt])&&p;p=pre[p])son[p][nxt]=np;
		if(!p)pre[np]=1;
		else{
			int q=son[p][nxt],nq;
			if(step[q]==step[p]+1)pre[np]=q;
			else{
				step[(nq=++cnt)]=step[p]+1;
				memcpy(son[nq],son[q],sizeof(son[q]));
				pre[nq]=pre[q];
				pre[np]=pre[q]=nq;
				for(;son[p][nxt]==q;p=pre[p])son[p][nxt]=nq;
			}
		}
	}
	void Toposort(){
		up(i,1,cnt)label[step[i]]++;
		up(i,1,N)label[i]+=label[i-1];
		up(i,1,cnt)rnk[label[step[i]]--]=i;
		down(i,cnt,1){
			int node=rnk[i];
			Right[pre[node]]+=Right[node];
		}
	}
	void Go(){
		now=1;int Len=0;
		up(i,1,(len<<1)-1){
			int nxt=s[i]-'a';
			for(;now&&(!son[now][nxt]);now=pre[now],Len=step[now]);
			if(!now){now=1;Len=0;}
			if(son[now][nxt]){now=son[now][nxt];Len++;}
			for(;now&&step[pre[now]]>=len;now=pre[now],Len=step[now]);
			if(step[pre[now]]<len&&step[now]>=len&&Len>=len){
				if(flag[now]!=M+1){
					ans+=Right[now];
					flag[now]=M+1;
				}
			}
		}
	}
}sam;
namespace solution{
	void Prepare(){
		scanf("%s",s+1);
		N=strlen(s+1);
		up(i,1,N)sam.Extend(s[i]-'a');
		sam.Toposort();
	}
	void Solve(){
		cin>>M;
		while(M--){
			scanf("%s",s+1);
			len=strlen(s+1);
			up(i,1,len-1)s[i+len]=s[i];
			ans=0;
			sam.Go();
			printf("%d\n",ans);
		}
	}
}
int main(){
	//freopen("input.in","r",stdin);
	using namespace solution;
	Prepare();
	Solve();
	return 0;
}

Codeforces 235C. Cyclical Quest的更多相关文章

  1. Codeforces 235C Cyclical Quest - 后缀自动机

    Some days ago, WJMZBMR learned how to answer the query "how many times does a string x occur in ...

  2. CodeForces 235C Cyclical Quest(后缀自动机)

    [题目链接] http://codeforces.com/contest/235/problem/C [题目大意] 给出一个字符串,给出一些子串,问每个子串分别在母串中圆环匹配的次数,圆环匹配的意思是 ...

  3. Codeforces 235C Cyclical Quest 字符串 SAM KMP

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF235C.html 题目传送门 -  CF235C 题意 给定一个字符串 $s$ ,多组询问,每组询问的形式为 ...

  4. CF 235C. Cyclical Quest [后缀自动机]

    题意:给一个主串和多个询问串,求询问串的所有样子不同的周期同构出现次数和 没有周期同构很简单就是询问串出现次数,|Right| 有了周期同构,就是所有循环,把询问串复制一遍贴到后面啊!思想和POJ15 ...

  5. Cyclical Quest CodeForces - 235C (后缀自动机)

    Cyclical Quest \[ Time Limit: 3000 ms\quad Memory Limit: 524288 kB \] 题意 给出一个字符串为 \(s\) 串,接下来 \(T\) ...

  6. 【Codeforces235C】Cyclical Quest 后缀自动机

    C. Cyclical Quest time limit per test:3 seconds memory limit per test:512 megabytes input:standard i ...

  7. 【CF235C】Cyclical Quest(后缀自动机)

    [CF235C]Cyclical Quest(后缀自动机) 题面 洛谷 题解 大致翻译: 给定一个串 然后若干组询问 每次也给定一个串 这个串可以旋转(就是把最后一位丢到最前面这样子) 问这个串以及其 ...

  8. 【CodeForces - 235C】Cyclical Quest 【后缀自动机】

    题意 给出一个字符串s1和q个询问,每个询问给出一个字符串s2,问这个询问的字符串的所有不同的周期串在s1中出现的次数的和. 分析 对于s1建后缀自动机.对于询问的每个字符串s2,我们按照处理循环串的 ...

  9. Cyclical Quest CodeForces - 235C 后缀自动机

    题意: 给出一个字符串,给出一些子串,问每个子串分别在母串中圆环匹配的次数, 圆环匹配的意思是将该子串拆成两段再首位交换相接的串和母串匹配,比 如aaab变成baaa,abaa,aaba再进行匹配. ...

随机推荐

  1. Location 对象的assign()和replace()有什么区别?

    window.location.assign(url) : 加载 URL 指定的新的 HTML 文档. 就相当于一个链接,跳转到指定的url,当前页面会转为新页面内容,可以点击后退返回上一个页面. w ...

  2. flask--简记

    Jinjia变量过滤器: safe 渲染值时不转义 capitalize 把值的首字母转换成大写,其他字母转换成小写 lower 把值转换成小写形式 upper 把值转换成大写形式 title 把值中 ...

  3. Hibernate中的映射关系(一对多)

    在数据库中表和表之间的关系有几种,(一对一,一对多,多对多)一对一关系:可以选择任意一方插入外键(one-to-one:one-to-one<--->many-to-one[unique= ...

  4. 修改记事本默认编码为UTF-8

    1. 新建一个txt文档,不输入任何内容.然后“另存为”,将编码由默认的 ANSI 修改为 Unicode 或 UTF-8,并将新文档命名为 temp.txt 2.将 temp.txt 移动至系统目录 ...

  5. 给NavigationBar设置颜色

    传统的设置 ) { [[UINavigationBar appearance] setBarTintColor:[UIColor redColor]]; } else { [[UINavigation ...

  6. Cookies and Session Tracking Client Identification cookie与会话跟踪 客户端识别

    w HTTP The Definitive Guide Cookies can be used to track users as they make multiple transactions to ...

  7. 【opencv】ubuntu opencv imshow()报错

    错误提示: ubuntu opencv imshow() 报错 windows.cpp报错 the function is not implemented If you are on Ubuntu o ...

  8. 微信js分享朋友圈(二)

    近期又用到微信分享的功能了.虽然不是第一次用了,依然我又有幸踩到了一个坑,所以分享一下吧. 根据微信sdk写的代码一步步很顺利,但是后面就是获取微信返回的分享结果的回调的时候IOS老是有问题,然后就网 ...

  9. scrollend,滚动结束执行一次

    var timer;window.onscroll = function () { clearTimeout(timer); timer = setTimeout(function () { aler ...

  10. 13.Query for Null or Missing Fields-官方文档摘录

    1 插入数据 db.inventory.insertMany([ { _id: 1, item: null }, { _id: 2 } ]) 2 查询null值 db.inventory.find({ ...