HDOJ 5421 Victor and String 리 턴 문자열 자동 동기

3866 단어
1 을 조작 하지 않 았 다 면 누 드 리 플 렉 스 자동 동기...
머리 에 문 자 를 삽입 할 수 있 는 리 턴 문자열 자동 동기 로 last 점 두 개 를 유지 하면 됩 니 다..............................................
전체 꼬치 가 답장 꼬치 일 때 두 개의 last 를 통일 하 세 요.
Victor and String
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/262144 K (Java/Others) Total Submission(s): 30    Accepted Submission(s): 9
Problem Description
Victor loves to play with string. He thinks a string is charming as the string is a palindromic string.
Victor wants to play 
n  times. Each time he will do one of following four operations.
Operation 1 : add a char 
c  to the beginning of the string.
Operation 2 : add a char 
c  to the end of the string.
Operation 3 : ask the number of different charming substrings.
Operation 4 : ask the number of charming substrings, the same substrings which starts in different location has to be counted.
At the beginning, Victor has an empty string.
 
Input
The input contains several test cases, at most 
5  cases.
In each case, the first line has one integer 
n  means the number of operations.
The first number of next 
n  line is the integer 
op , meaning the type of operation. If 
op =
1  or 
2 , there will be a lowercase English letters followed.
1≤n≤100000 .
 
Output
For each query operation(operation 3 or 4), print the correct answer.
 
Sample Input

   
   
   
   
6 1 a 1 b 2 a 2 c 3 4 8 1 a 2 a 2 a 1 a 3 1 b 3 4

 
Sample Output

   
   
   
   
4 5 4 5 11

 
Source
BestCoder Round #52 (div.1) ($)
 
/* ***********************************************
Author        :CKboss
Created Time  :2015 08 24      10 32 04 
File Name     :HDOJ5421.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

typedef long long int LL;

const int maxn=200100;
const int C=30;

int L,R;
int nxt[maxn][C];
int fail[maxn];
LL cnt[maxn];
LL num[maxn];
int len[maxn];
int s[maxn];
int last[2],p,n;
LL tot;

int newnode(int x)
{
	for(int i=0;i<C;i++) nxt[p][i]=0;
	num[p]=0; len[p]=x;
	return p++;
}

void init()
{
	p=0;
	newnode(0); newnode(-1);

	memset(s,-1,sizeof(s));
	L=maxn/2; R=maxn/2-1;
	last[0]=last[1]=0;
	fail[0]=1;

	tot=0;
}

/// d=0 add preffix d=1 add suffix

int getfail(int d,int x)
{
	if(d==0) while(s[L+len[x]+1]!=s[L]) x=fail[x];
	else if(d==1) while(s[R-len[x]-1]!=s[R]) x=fail[x];
	return x;
}

void add(int d,int c)
{
	c-='a';
	if(d==0) s[--L]=c;
	else s[++R]=c;

	int cur=getfail(d,last[d]);

	if(!nxt[cur][c])
	{
		int now=newnode(len[cur]+2);
		fail[now]=nxt[getfail(d,fail[cur])][c];
		nxt[cur][c]=now;
		num[now]=num[fail[now]]+1;
	}
	last[d]=nxt[cur][c];
	if(len[last[d]]==R-L+1) last[d^1]=last[d];
	tot+=num[last[d]];
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);

	int _;
	while(scanf("%d",&_)!=EOF)
	{
		init();
		while(_--)
		{
			int kind;
			char ch[5];
			scanf("%d",&kind);
			if(kind<=2)
			{
				kind--;
				scanf("%s",ch);
				add(kind,ch[0]);
			}
			else if(kind==3) printf("%d
",p-2); else if(kind==4) printf("%lld
",tot); } } return 0; }

좋은 웹페이지 즐겨찾기