UVALive - 4513 Stammering Aliens

1.題面

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2514

2,題意

給定一個字符串和一個數字m, 要求找出最少出現m次的最長的字符串,這些字符串之間可以重疊

3.思路

使用字符串hash或是後綴數組

4.代碼

/*****************************************************************
    > File Name: cpp_acm.cpp
    > Author: Uncle_Sugar
    > Mail: [email protected]
    > Created Time: Sat 20 Aug 2016 23:14:46 CST
*****************************************************************/
# include <cstdio>
# include <cstring>
# include <cctype>
# include <cmath>
# include <cstdlib>
# include <climits>
# include <iostream>
# include <iomanip>
# include <set>
# include <map>
# include <vector>
# include <stack>
# include <queue>
# include <algorithm>
using namespace std;

# define rep(i,a,b) for (i=a;i<=b;i++)
# define rrep(i,a,b) for (i=b;i>=a;i--)

template<class T>void PrintArray(T* first,T* last,char delim=' '){
    for (;first!=last;first++) cout << *first << (first+1==last?'\n':delim);
}

const int debug = 1;
const int size  = 10 + 40000; 
const int INF = INT_MAX>>1;
typedef unsigned long long ll;
const ll MOD = 1000000007;

/*
1.see the size of the input data before you select your algorithm 
2.cin&cout is not recommended in ACM/ICPC
3.pay attention to the size you defined, for instance the size of edge is double the size of vertex
*/

ll Count[size];

char s[size];
int len = 0;

ll hhash[size];

void pretreat(){
	hhash[0] = 0;
	for (int i = 1; i <= len; i++){
		hhash[i] = hhash[i-1] + (s[i-1] - 'a' + 1)*Count[i];
	}
}

ll key[size];
int rrank[size];
bool cmp(int a, int b){
	return key[a] < key[b];
}

int check(int m, int c){
	for (int i = m; i <= len; i++){
		rrank[i] = i;
		key[i] = (hhash[i] - hhash[i - m])*Count[len-i];
	}
	sort(rrank + m, rrank + len + 1, cmp);
	int cnt = 0, pos = 0;
	int right_most = -1;
	for (int i = m; i <= len; i++){
		if (i==m||key[rrank[i]] != key[rrank[i-1]]) {
			pos = rrank[i];	
			cnt = 1;	
		}else {
			pos = max(rrank[i], pos);
			cnt++;
		}
		if (cnt >= c) right_most = max(right_most, pos);
	}
	return right_most;
}

int main()
{
	/*std::ios::sync_with_stdio(false);cin.tie(0);*/
	Count[0] = 1;
	for (int i = 1; i < size; i++) Count[i] = Count[i-1]*MOD;
	int m;
	while (scanf("%d",&m) != EOF){
		if (!m) break;
		scanf("%s", s);
		len = strlen(s);
		pretreat();
		int l = 0, r = len + 1;
		int anspos = 0;
		while (l < r - 1){
			int mid = l+r>>1;
			int k = check(mid, m);
			if (k != -1){
				l = mid;	
				anspos = k;
			}else {
				r = mid;	
			}
		}
		if (l == 0)	
			printf("none\n");
		else 
			printf("%d %d\n",l ,anspos-l);
	}
	return 0;
}







發佈了150 篇原創文章 · 獲贊 30 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章