传送门

写的时候挺蛋疼的。

刚开始的时候思路没跑偏,无非就是建个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. 解决多指操作放大缩小 指针错误 java.lang.IllegalArgumentException: pointerIndex out of range

    /** Custom your own ViewPager to extends support ViewPager. java source: */ /** Created by azi on 20 ...

  2. Exchange Pause or stop transport service

    The Microsoft Exchange Transport service is a service available both on the Microsoft Exchange Serve ...

  3. Graphite grafana

    Graphite http://graphiteapp.org/ Graphite is an enterprise-ready monitoring tool that runs equally w ...

  4. Spark源码分析 – 汇总索引

    http://jerryshao.me/categories.html#architecture-ref http://blog.csdn.net/pelick/article/details/172 ...

  5. Junit 3.8.1 源码分析(一)

    写在前面:本文基于Junit3.8.1版本,因为这是我第一次进行源码学习,先从简单的源码开始学起 1. 示例代码 1.1 准备工作 下载Junit3.8.1的JAR包 需要下载junit-3.8.1- ...

  6. Visual Studio 2017 新特性

    1. out-variables(Out变量) 以前,我们使用out变量的时候,需要在外部先申明,然后才能传入方法,类似如下: string ddd = ""; //先申明变量 c ...

  7. 《Monitoring and Tuning the Linux Networking Stack: Receiving Data》翻译

    Overview 从宏观的角度来看,一个packet从网卡到socket接收缓冲区的路径如下所示: 驱动加载并初始化 packet到达网卡 packet通过DMA被拷贝到内核中的一个ring buff ...

  8. windows通过ssh连接虚拟机中的ubuntu步骤

    linux端开启ssh服务 1.安装openssh-server包 sudo apt-get install openssh-server 2.启动ssh server sudo /etc/init. ...

  9. 我不想用for循环

    为什么要挑战自己在代码里不写for loop?因为这样可以迫使你去使用比较高级.地道的语法或库.文中以python为例子,讲了不少大家其实在别人的代码里都见过.但自己很少用的语法. 这是一个挑战.我要 ...

  10. air游戏接入小米支付sdk

    小米支付sdk要求在Application.onCreate中进行初始化 为了这个初始化搞了半天,最终搞定了.今天将更改的步骤记录下了. 1. 创建ANE.ANE的创建就不罗嗦了,这里须要注意一点,这 ...