Marlon's String zoj3587

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4629

后缀数组或扩展kmp

SA做法

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>   
#include <map>
#include <string>  
#include <climits> 
#include <set>
#include <string>    
#include <sstream> 
#include <ctime>
#include <bitset>
#include <iomanip>
#pragma comment(linker, "/STACK:102400000,102400000")

using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::stringstream;
using std::make_pair;
using std::getline;
using std::greater;
using std::endl;
using std::multimap;
using std::deque;
using std::unique;
using std::lower_bound;
using std::random_shuffle;
using std::bitset;
using std::upper_bound;
using std::multiset;
using std::ios;
using std::make_heap;
using std::push_heap;
using std::pop_heap;

typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned UN;
typedef pair<int, int> PAIR;
typedef multimap<int, int> MMAP;
typedef long double LF;

const int MAXN(200010);
const int MAXM(20010);
const int MAXE(2100010);
const int MAXK(6);
const int HSIZE(1313131);
const int SIGMA_SIZE(26);
const int MAXH(19);
const int INFI((INT_MAX-1) >> 1);
const ULL BASE(31);
const LL LIM(1e13);
const int INV(-10000);
const int MOD(1000000007);
const double EPS(1e-7);
const LF PI(acos(-1.0));

template<typename T> inline bool checkmax(T &a, T b){if(b > a) { a = b; return true;} return false;}
template<typename T> inline bool checkmin(T &a, T b){if(b < a) { a = b; return true;} return false;}
template<typename T> inline T ABS(T a){return a < 0? -a: a;}
template<typename T> inline bool EZ(T a){return ABS(a) < EPS;}

int Log[MAXN];
void initLog(){
	Log[0] = -1;
	for(int i = 1; i < MAXN; ++i) Log[i] = (i&(i-1))? Log[i-1]: Log[i-1]+1;
}

struct SA{
	char S[MAXN];
	int sa[MAXN], t1[MAXN], t2[MAXN], cnt[MAXN], len, M;
	void init(int l, int m = 128){
		len = l;
		M = m;
		int *p1 = t1, *p2 = t2;
		for(int i = 0; i < M; ++i) cnt[i] = 0;
		for(int i = 0; i <= len; ++i) ++cnt[p1[i] = S[i]];
		for(int i = 1; i < M; ++i) cnt[i] += cnt[i-1];
		for(int i = len; i >= 0; --i) sa[--cnt[p1[i]]] = i;
		int temp = 1;
		for(int k = 1; temp <= len; k <<= 1){
			temp = 0;
			for(int i = len-k+1; i <= len; ++i) p2[temp++] = i;
			for(int i = 0; i <= len; ++i) 
				if(sa[i] >= k) p2[temp++] = sa[i]-k;
			for(int i = 0; i < M; ++i) cnt[i] = 0;
			for(int i = 0; i <= len; ++i) ++cnt[p1[p2[i]]];
			for(int i = 1; i < M; ++i) cnt[i] += cnt[i-1];
			for(int i = len; i >= 0; --i) sa[--cnt[p1[p2[i]]]] = p2[i];
			swap(p1, p2);
			temp = 1;
			p1[sa[0]] = 0;
			for(int i = 1; i <= len; ++i)
				p1[sa[i]] = p2[sa[i-1]] == p2[sa[i]] && p2[sa[i-1]+k] == p2[sa[i]+k]? temp-1: temp++;
			M = temp;
		}
	}
	int rank[MAXN], hei[MAXN];
	void getHei(){
		int k = 0;
		for(int i = 0; i <= len; ++i) rank[sa[i]] = i;
		for(int i = 0; i < len; ++i){
			if(k) --k;
			int j = sa[rank[i]-1];
			while(S[i+k] == S[j+k]) ++k;
			hei[rank[i]] = k;
		}
	}
	int dp[MAXH][MAXN];
	void initRMQ(){
		for(int i = 1; i <= len; ++i) dp[0][i] = hei[i];
		for(int i = 1; (1 << i) <= len; ++i)
			for(int j = 1; j+(1 << i)-1 <= len; ++j)
				dp[i][j] = min(dp[i-1][j], dp[i-1][j+(1 << (i-1))]);
	}
	int lcp(int a, int b){
		if(a == b) return len-a;
		if(a == len || b == len) return 0;
		a = rank[a];
		b = rank[b];
		if(a > b) swap(a, b);
		++a;
		int temp = Log[b-a+1];
		return min(dp[temp][a], dp[temp][b-(1 << temp)+1]);
	}
	int solve(int ind, int lim){
		ind = rank[ind];
		int ret = 0;
		int l = 0, r = ind;
		while(l < r){
			int m = (l+r) >> 1;
			if(lcp(sa[m], sa[ind]) >= lim) r = m;
			else l = m+1;
		}
		ret += ind-l+1;
		l = ind, r = len+1;
		while(l < r){
			int m = (l+r) >> 1;
			if(lcp(sa[m], sa[ind]) >= lim) l = m+1;
			else r = m;
		}
		--l;
		ret += l-ind+1;
		--ret;
		return ret;
	}
} sa1, sa2;

int main(){
	initLog();
	int TC;
	scanf("%d", &TC);
	while(TC--){
		scanf("%s%s", sa1.S, sa2.S);
		int len1 = strlen(sa1.S), len2 = strlen(sa2.S);
		sa1.S[len1] = 1;
		strcpy(sa1.S+len1+1, sa2.S);
		sa1.init(len1+len2+1);
		sa2.init(len2);
		sa1.getHei();
		sa2.getHei();
		sa1.initRMQ();
		sa2.initRMQ();
		LL ans = 0;
		for(int i = 1; i < len2; ++i){
			LL t1 = sa1.solve(len1+1, i);
			LL t2 = sa2.solve(0, i);
			LL t3 = t1-t2;
			t1 = sa1.solve(len1+1+i, len2-i);
			t2 = sa2.solve(i, len2-i);
			ans += t3*(t1-t2);
		}
		printf("%lld\n", ans);
	}
	return 0;
}


扩展kmp

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>   
#include <map>
#include <string>  
#include <climits> 
#include <set>
#include <string>    
#include <sstream> 
#include <ctime>
#include <bitset>
#include <iomanip>
#pragma comment(linker, "/STACK:102400000,102400000")

using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::stringstream;
using std::make_pair;
using std::getline;
using std::greater;
using std::endl;
using std::multimap;
using std::deque;
using std::unique;
using std::lower_bound;
using std::random_shuffle;
using std::bitset;
using std::upper_bound;
using std::multiset;
using std::ios;
using std::make_heap;
using std::push_heap;
using std::pop_heap;

typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned UN;
typedef pair<int, int> PAIR;
typedef multimap<int, int> MMAP;
typedef long double LF;

const int MAXN(100010);
const int MAXM(20010);
const int MAXE(2100010);
const int MAXK(6);
const int HSIZE(1313131);
const int SIGMA_SIZE(26);
const int MAXH(19);
const int INFI((INT_MAX-1) >> 1);
const ULL BASE(31);
const LL LIM(1e13);
const int INV(-10000);
const int MOD(1000000007);
const double EPS(1e-7);
const LF PI(acos(-1.0));

template<typename T> inline bool checkmax(T &a, T b){if(b > a) { a = b; return true;} return false;}
template<typename T> inline bool checkmin(T &a, T b){if(b < a) { a = b; return true;} return false;}
template<typename T> inline T ABS(T a){return a < 0? -a: a;}
template<typename T> inline bool EZ(T a){return ABS(a) < EPS;}
/*
template<typename TY, int N>
struct EXKMP{
	TY P[N];
	int lenp;
	int next[N];
	void getnext(){
		next[0] = lenp;
		int k = 1, l = 0, a = 1;
		while(k < lenp && P[k] == P[l]){
			++k;
			++l;
		}
		next[l] = 1;
		int i = 2;
		while(i < lenp){
			int temp = next[i-a];
			if(i+temp < k) next[i] = temp;
			else{
				checkmax(k, i);
				l = k-i;
				while(k < lenp && P[k] == P[l]){
					++k;
					++l;
				}
				next[i] = l;
				a = i;
			}
			++i;
		}
		next[lenp] = 0;
	}
	TY T[N];
	int lent;
	int extend[N];
	void getextend(){
		int i, a, p, j(-1);
		for(i = 0; i < lent; ++i, --j){
			if(j < 0 || i+next[i-a] >= p){
				if(j < 0) j = 0, p = i;
				while(p < lent && j < lenp && T[p] == P[j]) ++p, ++j;
				extend[i] = j, a = i;
			}
			else
				extend[i] = next[i-a];
		}
	}
};
*/
template<typename TY, int N>
struct EXKMP
{
	TY P[N];
	int lenp;
	int next[N]; //next[i]表示str[i...len-1] 与 str[0...len-1]的最长公共前缀
	void getnext()
	{
		next[0] = lenp;
		int k = 1, l = 0, a = 1; //含义: 当前位置, 匹配长度
		while(k < lenp && P[k] == P[l])
		{
			++k;
			++l;
		}
		next[1] = l;
		int i = 2;
		while(i < lenp)
		{
			int temp = next[i-a];
			if(i+temp < k) next[i] = temp;
			else
			{
				checkmax(k, i);
				l = k-i;
				while(k < lenp && P[k] == P[l])
				{
					++k;
					++l;
				}
				next[i] = l;
				a = i;
			}
			++i;
		}
		next[lenp] = 0;
	}
	TY T[N];
	int lent;
	int extend[N];
	void getextend()
	{
		int i, a, p, j(-1);
		for(i = 0; i < lent; ++i, --j)
		{
			if(j < 0 || i+next[i-a] >= p)
			{
				if(j < 0) j = 0, p = i;
				while(p < lent && j < lenp && T[p] == P[j]) ++p, ++j;
				extend[i] = j, a = i;
			}
			else extend[i] = next[i-a];
		}
	}
};

void rev(char *sp, int len){
	int l = 0, r = len-1;
	while(l < r){
		swap(sp[l], sp[r]);
		++l;
		--r;
	}
}

EXKMP<char, MAXN> exk;
int cnt1[MAXN], cnt2[MAXN];

int main(){
	int TC;	
	scanf("%d", &TC);
	while(TC--){
		scanf("%s%s", exk.T, exk.P);
		exk.lenp = strlen(exk.P);
		exk.lent = strlen(exk.T);
		exk.getnext();
		exk.getextend();
		memset(cnt1, 0, sizeof(cnt1[0])*(exk.lenp+1));
		for(int i = 0; i < exk.lent; ++i) ++cnt1[exk.extend[i]];
		for(int i = exk.lenp-1; i > 0; --i) cnt1[i] += cnt1[i+1];
		rev(exk.P, exk.lenp);
		rev(exk.T, exk.lent);
		exk.getnext();
		exk.getextend();
		memset(cnt2, 0, sizeof(cnt2[0])*(exk.lenp+1));
		for(int i = 0; i < exk.lent; ++i) ++cnt2[exk.extend[i]];
		for(int i = exk.lenp-1; i > 0; --i) cnt2[i] += cnt2[i+1];
		LL ans = 0;
		for(int i = 1; i < exk.lenp; ++i) ans += (LL)cnt1[i]*cnt2[exk.lenp-i];
		printf("%lld\n", ans);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是使用 Scala 语言编写一个简单的 Kafka 模拟电影信息的示例程序: ```scala import java.util.Properties import org.apache.kafka.clients.producer.{KafkaProducer, ProducerRecord} object MovieKafkaProducer { def main(args: Array[String]): Unit = { val props = new Properties() props.put("bootstrap.servers", "localhost:9092") props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer") props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer") val producer = new KafkaProducer[String, String](props) val topic = "movies" val movies = List( Movie("The Shawshank Redemption", "Frank Darabont", List("Tim Robbins", "Morgan Freeman"), List("Drama", "Crime"), 9.3), Movie("The Godfather", "Francis Ford Coppola", List("Marlon Brando", "Al Pacino"), List("Crime", "Drama"), 9.2), Movie("The Dark Knight", "Christopher Nolan", List("Christian Bale", "Heath Ledger"), List("Action", "Crime", "Drama"), 9.0) ) movies.foreach(movie => { val record = new ProducerRecord[String, String](topic, movie.name, movie.toJson()) producer.send(record) println(s"Sent movie: $movie") }) producer.close() } case class Movie(name: String, director: String, actors: List[String], genres: List[String], rating: Double) { def toJson(): String = { s"""{"name": "$name", "director": "$director", "actors": "${actors.mkString(",")}", "genres": "${genres.mkString(",")}", "rating": $rating}""" } } } ``` 这个程序使用 KafkaProducer 发送电影信息到 Kafka 的 `movies` 主题中。在发送电影信息时,将电影信息转换为 JSON 格式,并使用电影名称作为 Kafka 记录的 key。同时,也输出了发送的电影信息。 需要注意的是,Scala 提供了很多 JSON 序列化和反序列化的库,例如 spray-json、Argonaut、circe 等,可以使用这些库来简化 JSON 格式的转换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值