题目大意

 
对于给定的字符串A和B,求出满足要求的集合S的大小。

题目分析

poj_3415

实现(c++)

 

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
#define LETTERS 60
#define MAX_ARRAY_SIZE 200005

int gSuffixArray[MAX_ARRAY_SIZE];
int gCount[MAX_ARRAY_SIZE];
int gOrderBySecondKey[MAX_ARRAY_SIZE];
int gRank[MAX_ARRAY_SIZE];
int gFirstKeyArray[MAX_ARRAY_SIZE];
int gHeight[MAX_ARRAY_SIZE];

int gStr[MAX_ARRAY_SIZE];
int gStrLen;

bool Compare(int* arr, int a, int b, int step){
	return arr[a] == arr[b] && arr[a + step] == arr[b + step];
}

void GetStr(char* str){
	memset(gStr, 0, sizeof(gStr));
	gStrLen = strlen(str);
	for (int i = 0; i < gStrLen; i++){
		if (str[i] >= 'a'){
			gStr[i] = str[i] - 'a' + 27;
		}
		else{
			gStr[i] = str[i] - 'A' + 1;
		}
	}
	gStr[gStrLen] = 0;
	gStrLen++;
}
//求后缀数组
void GetSuffixArray(){
	int n = gStrLen;
	memset(gCount, 0, sizeof(gCount));
	for (int i = 0; i < n; i++){
		gRank[i] = gStr[i];
		gCount[gRank[i]] ++;
	}
	int m = LETTERS;
	for (int i = 1; i < m; i++){
		gCount[i] += gCount[i - 1];
	}
	for (int i = n - 1; i >= 0; i--){
		gSuffixArray[--gCount[gRank[i]]] = i;
	}

	int step = 1;
	int *rank = gRank, *order_by_second_key = gOrderBySecondKey;
	while (step < n){
		int p = 0;

		for (int i = n - step; i < n; i++){
			order_by_second_key[p++] = i;
		}
		for (int i = 0; i < n; i++){
			if (gSuffixArray[i] >= step){
				order_by_second_key[p++] = gSuffixArray[i] - step;
			}
		}
		for (int i = 0; i < n; i++){
			gFirstKeyArray[i] = rank[order_by_second_key[i]];
		}
		for (int i = 0; i < m; i++){
			gCount[i] = 0;
		}
		for (int i = 0; i < n; i++){
			gCount[gFirstKeyArray[i]] ++;
		}
		for (int i = 1; i < m; i++){
			gCount[i] += gCount[i - 1];
		}
		for (int i = n - 1; i >= 0; i--){
			gSuffixArray[--gCount[gFirstKeyArray[i]]] = order_by_second_key[i];
		}
		int* tmp = rank; rank = order_by_second_key; order_by_second_key = tmp;
		rank[gSuffixArray[0]] = p = 0;
		for (int i = 1; i < n; i++){
			if (Compare(order_by_second_key, gSuffixArray[i], gSuffixArray[i - 1], step)){
				rank[gSuffixArray[i]] = p;
			}
			else{
				rank[gSuffixArray[i]] = ++p;
			}
		}
		m = p + 1;
		step *= 2;
	}
}
//求height数组
void GetHeight(){
	int n = gStrLen;
	for (int i = 0; i < n; i++){
		gRank[gSuffixArray[i]] = i;
	}
	int k = 0, j;
	for (int i = 0; i < n; i++){
		if (k){
			k--;
		}
		j = gSuffixArray[gRank[i] - 1];
		while (j + k < n && i + k < n&& gStr[i + k] == gStr[j + k]){
			k++;
		}
		gHeight[gRank[i]] = k;
	}
}
int min(int a, int b){
	return a < b ? a : b;
}
int gStack[MAX_ARRAY_SIZE][2];
long long int Find(int k, int n){
	int end = 1;
	long long int sum = 0, tot = 0;
	int top = -1, count = 0;
	while (end < gStrLen){		
		if (gHeight[end] < k){
			count = 0;
			tot = 0;
			top = -1;
		}
		else{
			count = 0;
			if (gSuffixArray[end - 1] < n){
				tot += (gHeight[end] - k + 1);
				count++;
			}
			while (top >= 0 && gStack[top][0] >= gHeight[end]){
				tot -= gStack[top][1] * (gStack[top][0] - gHeight[end]);
				count += gStack[top][1];
				top--;
			}
			top++;
			gStack[top][0] = gHeight[end];
			gStack[top][1] = count;
			if (gSuffixArray[end] > n){
				sum += tot;
			}
		}		
		end++;
	}
	end = 1;
	tot = 0;
	count = 0;
	top = -1;
	while (end < gStrLen){
		if (gHeight[end] < k){
			tot = 0;
			count = 0;
			top = -1;
		}
		else{
			count = 0;
			if (gSuffixArray[end - 1] > n){
				count++;
				tot += (gHeight[end] - k + 1);
			}
			while (top >= 0 && gStack[top][0] >= gHeight[end]){
				tot -= (gStack[top][1])*(gStack[top][0] - gHeight[end]);
				count += gStack[top][1];
				top--;
			}
			top++;
			
			gStack[top][0] = gHeight[end];
			gStack[top][1] = count;

			if (gSuffixArray[end] < n){
				sum += tot;
			}
		}
		end ++;
	}
	return sum;
}
char str[MAX_ARRAY_SIZE];
int main(){
	int len1, len2, k;
	while (scanf("%d", &k) != EOF){
		if (k == 0){
			break;
		}
		scanf("%s", str);
		len1 = strlen(str);
		str[len1] = 'a' + 27;
		scanf("%s", str + len1 + 1);
		GetStr(str);
		GetSuffixArray();
		GetHeight();
	
		long long int sum = Find(k, len1);
		
		printf("%lld\n", sum);
	}
	return 0;
}

 

相关文章:

  • 2021-07-17
  • 2022-12-23
  • 2021-10-02
  • 2021-06-06
  • 2021-10-05
  • 2021-10-12
  • 2022-02-24
  • 2021-05-16
猜你喜欢
  • 2022-01-07
  • 2022-01-26
  • 2021-09-26
  • 2021-06-08
  • 2021-10-31
  • 2022-12-23
  • 2022-01-16
相关资源
相似解决方案